ZOJ-1937 Addition Chains(迭代搜索)

/*
1937Addition Chains

--------------------------------------------------------------------------------

Time Limit: 1 Second      Memory Limit: 32768 KB      Special Judge

--------------------------------------------------------------------------------

An addition chain for n is an integer sequence with the following four properties:

a0 = 1
am = n
a0 < a1 < a2 < ... < am-1 < am
For each k (1 <= k <= m) there exist two (not necessarily different) integers i and j (0 <= i, j <= k-1) with ak = ai + aj
You are given an integer n. Your job is to construct an addition chain for n with minimal length. If there is more than one such sequence, any one is acceptable.

For example, <1, 2, 3, 5> and <1, 2, 4, 5> are both valid solutions when you are asked for an addition chain for 5.


Input

The input will contain one or more test cases. Each test case consists of one line containing one integer n (1 <= n <= 100). Input is terminated by a value of zero (0) for n.


Output

For each test case, print one line containing the required integer sequence. Separate the numbers by one blank.

 

Sample Input


5
7
12
15
77
0


Sample Output

1 2 4 5
1 2 4 6 7
1 2 4 8 12
1 2 4 5 10 15
1 2 4 8 9 17 34 68 77


迭代搜索,用深度优先的话需要找出所有加法链,然后再取最小的,至少是n!的复杂度,用广度的话
找到的第一个加法链就是最短的,但是对空间占用太大
逐步深化的迭代搜索可以保证第一个找到的加法链就是最短的,又不需要太大的空间开销。
基本思想是控制回溯的搜索深度deep, 每次使deep加1,直到找到一条加法链

(更多优化):1.deep有一个下界,从此下界开始搜索,可以最大加快搜索进程
 2.更多剪枝
 3.最短加法链的上界,是一个幂树。
*/
#include
using namespace std;
int n;
int v[50];
int re[50];
bool found;
int deep,best;
void dfs(int i)
{
    if(!found)
    {
        if(v[i]==n)
  {   
            best=i;
            for(int j=0;j<=i;++j)
                re[j]=v[j];
   found=true;
   return;
        }
        else if(i            for(int j=i;j>=0;--j)
                if(v[j]*2>v[i])
                    for(int k=j;k>=0;--k)
                        if(v[j]+v[k]>v[i]&&v[j]+v[k]<=n)
                        {   
                            v[i+1]=v[j]+v[k];
                            dfs(i+1);
                        }                  
    }
}
int main()
{
    while(cin>>n&&n>0)
    {
  found=false;
  deep=2;best=n;
        while(!found)
        {
            v[0]=1;
            dfs(0);
            deep++;
        }
        for(int i=0;i<=best;++i)
            cout<        cout<  
    }
    return 0;
}

你可能感兴趣的:(数学,算法)