题目链接;http://poj.org/problem?id=2248
要求给出一个严格递增的数列,首元素是1,尾元素是n,并且要求最短。
可以得知,在一百以内的最优策略中,搜索的深度不会超过10,深度最坏的情况下是有100层的,而且深处数的分支会越来越多,考虑到层数最多是10层,所以我们可以考虑使用
迭代加深搜索不断对层数进行扩展直到找到一个最优解。迭代,就是利用上一次计算的结果,重复进行同样的操作并且逐渐逼近最优解的过程。在这个问题中我们对于每个结点需要记录
尝试过的数,同样的数一样不会成功的,一旦成功,那么结果就是depth,因为前面depth-1层是没有搜到正确答案的。
代码:
#include<iostream> #include<string.h> using namespace std; #define maxn 100 int ans[maxn],n; int depth=1; bool dfs(int dep){//dep表示已经完成的层数 if(dep==depth)return ans[dep]==n; bool vis[200]; memset(vis,0,sizeof(vis));//标记在这个结点处进行扩展中已经扩展的数,不会重复进行搜索 for(int i=dep;i;i--)//从最大的数开始搜索,能够更快的接近n for(int j=i;j;j--){ int num=ans[i]+ans[j]; if(vis[num] || num<=ans[dep] || num>n)continue; vis[ans[i]+ans[j]]=1; ans[dep+1]=ans[i]+ans[j]; if(dfs(dep+1))return true; } return false; } int main(){ while(cin>>n && n){ memset(ans,0,sizeof(ans)); depth=1;//最初迭代加深搜索的深度是1 ans[1]=1; while(!dfs(1))depth++; for(int i=1;i<=depth;i++)printf("%d ",ans[i]); cout<<endl; } }