POJ 3134 Power Calculus IDA*

题目大意,循环读入一个1~1000的数字n,你现在只有一个数x,你的任务是输出得到x^n需要的最小步数,你可以使用当前循环里得到的任意数,题里的x^31,可以通过如下步骤

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

然后我懵逼四十分钟,乱搞十分钟,IDA*水过

我们不难发现,x^n与x无关,所以我们只需要看n,于是我们可以发现,x^a1*x^a2=x^(a1+a2),x^a1/x^a2=x^(a1-a2),我们完全不需要乘乘除除,只需要加减即可,模拟用最少的加减次数达到n

用一个ans数组,存储第i步时,达到的和,IDA*时,当前deepth+1在ans中的值可以是ans[deepth]+ans[1~deepth],相当于模拟x^deepth*x^(1~deepth),也可以是ans[deepth]-ans[1~deepth],相当于模拟x^deepth / x^(1~deepth),如果当前IDA*的deepth在ans中的值==n,return 1;

剪枝,如果当前搜索到的deepth在ans中的值的limit次方(当前递归的限制深度)都达不到n,那么就直接return 0,因为就算当前递归的最大值就是ans[deepth]^limlit,他都小于n,那么ans[deepth]加上deepth小于当前深度的deepth在ans中的值永远不可能达到n,显然对吧,ok,看代码

By Acer.Mo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int x;
int lim;
int ans[5000];
int IDAS(int limdep)
{
	if (limdep>lim) return 0;
	if ((ans[limdep]<<lim-limdep)<x) return 0;//剪枝
	if (ans[limdep]==x) return 1;
	for (int i=0;i<=limdep;i++)
	{
		ans[limdep+1]=ans[limdep]+ans[i];
		if (IDAS(limdep+1)) return 1;//乘方
		ans[limdep+1]=ans[limdep]-ans[i];
		if (IDAS(limdep+1)) return 1;//除
	}
	return 0;
}
int main()
{
	ans[0]=1;
	while (~scanf("%d",&x)&&x)
	{
		for (lim=0;;lim++)
		if (IDAS(0)) break;
		printf("%d\n",lim);
	}
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值