UVA529 Addition Chains

UVA529 Addition Chains

题意翻译

题目描述

一个与 nn 有关的整数加成序列 <a_0,a_1,a_2,...,a_m><a0,a1,a2,...,am> 满足以下四个条件:
1.a_0=11.a0=1
2.a_m=n2.am=n
3.a_0<a_1<a_2<...<a_{m-1}<a_m3.a0<a1<a2<...<am1<am
4.4. 对于每一个 k(1≤k≤m)k(1km) 都存在有两个整数 ii 和 j(0≤i,j≤k-1,ij(0i,jk1,i 和 jj 可以相等 )) ,使得 a_k=a_i+a_jak=ai+aj
你的任务是:给定一个整数 nn ,找出符合上述四个条件的长度最小的整数加成序列。如果有多个满足要求的答案,只需要输出任意一个解即可。
举个例子,序列 <1,2,3,5><1,2,3,5> 和 <1,2,4,5><1,2,4,5> 均为 n=5n=5 时的解。

输入格式

输入包含多组数据。每组数据仅一行包含一个整数 n(1≤n≤10000)n(1n10000) 。在最后一组数据之后是一个 00 。

输出格式

对于每组数据,输出一行所求的整数加成序列,每个整数之间以空格隔开。

  • 迭代加深搜索,细节很多
  • 代码

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 
 5 #define res register int
 6 const int N=10005;
 7 int a[N],n,dep;
 8 
 9 inline void init()
10 {
11     memset(a,0,sizeof(a));
12     a[1]=1; a[2]=2; dep=0;
13     int tmp(1);
14     while(tmp<n)
15     {
16         tmp<<=1;
17         dep++;
18     }
19 }
20 
21 inline bool dfs(int x)
22 {
23     if(x>dep) {
24         if(a[dep]==n) return true;
25         return false;
26     }
27     if(a[x-1]<<(dep-x+1)<n) return false;
28     for(res i=x-1 ; i>=1 ; i--)
29         for(res j=i ; j>=1 ; j--)
30         {
31             int sum=a[i]+a[j]; 
32 //            if(sum==7) printf("i %d ai %d j %d aj %d\n",i,a[i],j,a[j]);
33             if(sum<=n)
34             {
35                 if(sum<=a[x-1]) return false;
36                 a[x]=sum;
37                 if(dfs(x+1)) return true;
38             }
39         }
40     return false;
41 }
42 
43 int main()
44 {
45     a[1]=1; a[2]=2;
46     while(scanf("%d",&n) && n)
47     {
48         init();
49         while(!dfs(3)) dep++;
50         printf("%d",a[1]);
51         for(res i=2 ; i<=dep ; i++) printf(" %d",a[i]);
52         printf("\n");
53         
54     }
55     return 0;
56 }
View Code

 

posted @ 2019-02-13 23:12  孑行  阅读(567)  评论(0编辑  收藏  举报