ZOJ1937:Addition Chains——题解
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1937
题目大意:创造一个数列,使得它:
1.单调不递减。
2.其中一个元素一定存在其前面两个元素之和与它相等。
3.开头为1,结尾为n。
求一个这样的最短数列。
——————————————————————————————————
IDA*一定的(n<=100)
对于IDA*是什么不了解的,可以看我的置顶骑士精神那道题。
我们的估价函数就是当前的值翻多少次二倍后能得到n。
显然假设当前的值为i,则答案为log2(n/i)。
然后就是和普通的IDA*一样做了。
(第1条不要忘了,我就是被这样坑过TAT)
#include<cstdio> #include<cstring> #include<cctype> #include<iostream> #include<cmath> using namespace std; int n,ans,a[5001]; inline int h(int step){ if(a[step]==n)return -1; return log(n/a[step])/log(2); } inline bool dfs(int step){ if(step==ans){ if(h(step)==-1)return 1; return 0; } if(h(step)+step>ans)return 0; for(int i=step;i>=1;i--){ for(int j=i;j>=1;j--){ if(a[i]+a[j]>n||a[i]+a[j]<a[step])continue; a[step+1]=a[i]+a[j]; if(dfs(step+1))return 1; } } return 0; } int main(){ a[1]=1; while(scanf("%d",&n)!=EOF&&n){ for(ans=1;;ans++){ if(dfs(1))break; } printf("%d",a[1]); for(int i=2;i<=ans;i++)printf(" %d",a[i]); printf("\n"); } return 0; }