▼页尾

[Project Euler] Problem 14

The following iterative sequence is defined for the set of positive integers:

n → n/2 (n is even)
n → 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

Which starting number, under one million, produces the longest chain?

NOTE: Once the chain starts the terms are allowed to go above one million.

 

寻找小于1,000,000的按Collatz Problem规律能形成最长序列的数

有两种思路:

首先,直接暴力搜索,按问题的规模来说,应该不是特别慢

第二种,动态规划,先把小的数的解的结果保存起来,若大数转化为小数,直接利用小数的解求得大数的解

 

我们来对比一下两种求法的效率

#include <iostream>
#include
<ctime>
#include
<cstdlib>
using namespace std;

const int NUM = 100000;
int flag[NUM+1]={0};

int search(long long i,int limit){
int tmp = i;
int len = 0;
while(i != 1){
if(i%2 == 0){
len
++;
i
= i/2;
if(i<limit && i<tmp){
len
+= flag[i];
if(tmp < limit){
flag[tmp]
= len;
}
return len;
}
}
else{
i
= 3*i+1;
len
++;
}
}
return len;
}


int search2(long long i){
int len=1;
while(i != 1){
if(i%2 == 0){
i
/= 2;
}
else{
i
= 3*i+1;
}
len
++;
}
return len;
}

int main(){
int max=0, limit=NUM;
int which=0;
int tmp;
long long i = 1;
clock_t start,finish;

for(int j=0;j<3;j++){
i
=1;
max
= 0;
start
= clock();
while(i < 1000000){
tmp
= search(i,limit)+1;
if(max < tmp){
max
= tmp;
which
= i;
}
i
++;
}
finish
= clock();
cout
<< max << '\t' << which << '\t' ;
cout
<< "Time :" << finish-start << '\t';
cout
<< "limit :" << limit << endl;
limit
/= 10;
}


i
= 1;
max
= 0;
start
= clock();
while(i < 1000000){
tmp
= search2(i);
if(max < tmp){
max
= tmp;
which
= i;
}
i
++;
}
finish
= clock();
cout
<< max << '\t' << which << '\t' ;
cout
<< "Time :" << finish-start << endl;

return 0;
}

 

 

我们可以看到,保存的小数的解越多,整个计算的过程也就越快

而直接暴力搜索总是最慢的

 

还有一点要注意的是,一个在1,000,000以下的数,按规律计算,计算的过程中,可能得到非常大的数,

会超过int的范围,所以要声明为long long型。我在网上看到有人声明为unsigned long型,虽然结果是对的,

但其实计算已经出现了错误,实际上是直接把超出int的部分截断了。

 

 

posted @ 2011-02-24 13:52  xiatwhu  阅读(652)  评论(6编辑  收藏  举报
▲页首
西