Addition Chains |
An addition chain for n is an integer sequence with the following four properties:
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.
Hint: The problem is a little time-critical, so use proper break conditions where necessary to reduce the search space.
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
迭代加深dfs很适合n=10000,17个数字,虽然感觉上迭代本身存在大量重复计算,但是重复的搜索树的深度小;
迭代加深搜索算法就是仿广度优先搜索的深度优先搜索。既能满足深度优先搜索的线性存储要求,又能保证发现一个最小深度的目标结点。
#include <string.h> #include <stdio.h> int a[100],best[100],n,min,f; int minlen(int num,int len) {int x=num,y=len; while (x<n) {x=x<<1;++y;} return y; } void dfs(int len) { int i,j,time,x; if ((a[len]==n)&&(len<min)) {f=0; min=len; for (i=1;i<=len;i++) best[i]=a[i]; } if ((a[len]>=n)||(len>=min)) return ; if (minlen(a[len],len)>=min) return ; for (i=1;i<=len;i++) for (j=i;j<=len;j++) { a[len+1]=a[i]+a[j]; if (a[len+1]>a[len]) dfs(len+1); } } int main() { int i; a[1]=1; a[2]=2; best[1]=1; best[2]=2; while (scanf("%d",&n),n) { f=1; min=minlen(2,2)-1; if (n<=2) {min=n;f=0;} while (f) {++min; dfs(2); } for (i=1;i<min;i++) printf("%d ",best[i]); printf("%d\n",n); } return 0; }