IDA*

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值