POJ 3134 Power Calculus (IDA*)

题目类型  搜索题(IDA*)

题目意思
起始的值是 x 问至少经过多少次操作能得到 x ^ n
每次操作是在上一次操作的基础上乘以或除以之前算出过的 x 的幂
例如输入 n = 2的话只需一次 即 x * x = x ^ 2 
输入n = 31的话要  6 次操作
第1步 x * x = x ^ 2
第2步 x^2 * x^2 = x ^ 4
第3步 x^4 * x^4 = x ^ 8
第4步 x^8 * x^8 = x ^ 16
第5步 x^16 * x^16 = x^32
第6步 x^32 / x = x ^ 31

解题方法
那么可以用迭代加深 + A*  剪枝的方法来做 即 IDA*
不断加大搜索的深度 每层搜索就用前一步得出的值和之前产生的所有值进行乘或除运算得出新的值
剪枝 : 假设当前已经算出来的x的幂的次方数最大是 n_max 那么如果还可以深入搜索 3 层的话 x 的次方数最多只可能变成 n_max << 3 
            所以如果 n_max << (还剩下的搜索层数) < n 的话已经没有继续搜索的必要 回退

参考代码 - 有疑问的地方在下方留言 看到会尽快回复的
#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int maxH, n, nc, n_max;
int num[110];

bool DFS(int tc) {
	if(num[nc-1] == n) return true;
	if(n_max * (1<<(maxH-tc)) < n) return false;
	if(tc == maxH) return false;
	for( int i=0; i<nc; i++ ) {
		num[nc] = num[nc-1] + num[i]; nc++;
		int tmp = n_max;
		n_max = max(n_max, num[nc-1]);
		if(DFS(tc+1)) return true;
		n_max = tmp;
		nc--;
	}
	for( int i=0; i<nc; i++ ) {
		num[nc] = num[nc-1] - num[i]; nc++;
		if(DFS(tc+1)) return true;
		nc--;
	}
	return false;
}

int main() {
	while(scanf("%d", &n), n) {
		maxH = 0;
		num[nc=0] = 1; nc = 1;
		while(DFS(0) == false) {
			num[nc=0] = 1;
			n_max = 1;
			nc = 1;
			maxH++;
		}
		printf("%d\n", maxH);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值