《算法竞赛进阶指南》0x24迭代加深搜索 POJ2248

题目链接;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;
    } 
}

 

posted @ 2020-06-19 17:05  WA自动机~  阅读(150)  评论(0编辑  收藏  举报