Addition Chains-------(迭代+深搜)
Time limit 2000 ms
Memory limit 65536 kB
题目描述:
An addition chain for n is an integer sequence <a0, a1,a2,...,am> 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.
输入:
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.
输出:
For each test case, print one line containing the required integer sequence. Separate the numbers by one blank.
输入样例:
5
7
12
15
77
0输出样例:
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,从1变化到n,这个过程需要的最少变化次数mi,a0,a1……ami;这个过程中ai之间的相加方式k=ai+aj,
这里面ai可以等于aj。深搜的过程中只要找到符合最短变化路径的数组即可,答案不唯一。
代码如下:
#include<stdio.h>
int n,mi;
int a[120],s[120];
void dfs(int x,int y)
{
if(y>mi) //对于超过前面长度的路径进行返回,没必要再搜下去了
return;
if(x==n) //符合要找的数
{
mi=y; //更新路径长度
for(int i=0; i<y; i++) //进行代替
s[i]=a[i];
return ;
}
for(int i=y-1; i>=0; i--)
{
int k=a[i]+x;
if(k<=n) //这里显然只有k<=n才满足条件得以继续深搜
{
a[y]=k; //存入数组中
dfs(k,y+1); //更改深搜的数,路径加1
}
}
}
int main()
{
while(~scanf("%d",&n)&&n)
{
mi=0x3f3f3f; //因为求最小,初始化为无穷大进行比较
a[0]=1; //所有符合输入的开始第一个数都为1,其实第二个也都为2,但是输入的n有可能就是1
dfs(1,1); //深搜的前者代表数的更改,后者代表路径大小
for(int i=0; i<mi-1; i++)
printf("%d ",s[i]);
printf("%d\n",s[mi-1]);
}
return 0;
}