题目 poj 3134
题目链接https://vjudge.net/problem/POJ-3134
前言:
说一下IDA*是对迭代加深搜索的优化,加一个估价函数,预测出当前DFS的状态不再搜索下去,就可以直接返回,提高了效率。简单说,就是在IDDFS过程中利用估价函数进行剪枝操作。
题目分析:
翻译:等价于从数字1开始,用加减法,最少算多少次才能得到n。(这样清楚多了吧!)
难点:如果每一步进行搜索,新值的数量增长非常快。直接DFS深度可能有1000很大概率就溢出了,如果用BFS也可能超出队列范围。所以!!IDA*啊!
1、IDDFS:指定递归深度,每一次做DFS时不超过这个深度
2、估价函数:如果当前的值用最快的方式都不能达到n,停止用这个值DFS
不多说了,上代码
AC:
#include<iostream>
#include<math.h>
using namespace std;
int val[1010];//保存一个搜索路径上每一步的计算结果
int pos,n;
bool ida(int now,int depth){
if(now>depth) return false;//IDDFS:大于当前设定的DFS深度,退出
if(val[pos]<<(depth-now)<n) return false;//估价函数,最快的倍增都达不到n,退出
if(val[pos] == n) return true; //当前结果等于n,结束
pos++;
for(int i = 0;i<pos;i++){
val[pos] = val[pos - 1]+val[i];//上一个数与前面所有的数相加
if(ida(now+1,depth)) return true;
val[pos] = abs(val[pos - 1] - val[i]);//上一个数与前面所有的数相减
if(ida(now + 1,depth)) return true;
}
pos--;
return false;
}
int main()
{
while(cin>>n&&n){
int depth;
for(depth = 0;;depth++){//每次只DFS到深度depth
val[pos = 0] = 1;//初始值是1
if(ida(0,depth)) break;//每次都从0层开始DFS到第depth层
}
cout<<depth<<endl;
}
return 0;
}