POJ1945 Power Hungry Cows (BFS)

来源:互联网 发布:java无参数函数调用 编辑:程序博客网 时间:2024/06/07 13:34

题目大意:自己感觉非常奇葩的一道搜索题。给出n,求x^n。最先给出的两个数为x^1和x^0,可以执行如下操作:两个数相乘,其中一个数平方,两个数相除。问要达到x^n的最少步数。


思路:把此题说得简单一点就是给定两个加数a = 1, b = 0;(在这里我们规定a总是大于b)每一部可以执行a*2,b*2,a-b之一的操作,使得目标状态达到n,每次操作之后新得到的值要替换掉原来的一个数。例如当a = 16,b = 2我们可以得到以下状态:

a = 32,b = 2;   a = 32, b = 16;   a = 16, b = 4;   a = 2,b = 4;   a = 12 ;   a = 18,b = 2;   a = 18, b = 16;    a = 14,b = 2;   a = 16,b = 14;

然后剩下的就是搜索的问题了。

考虑以下情况可以剪枝:显然a = b是可以剪掉的;如果a超过目标状态n太多是没有最优解的,同理,b太大也是没有最优解的。只是我没有完全弄清楚为什么b大于100左右,a超过n 100 左右是没有最优解的。

#include<cstdio>#include<iostream>#define MAXN 800000using namespace std;struct T{int num1,num2,step;}q[MAXN];bool vis[20500][105];int n;int head,tail;bool add(int num1,int num2,int step)//其实就是一个BFS,维护num1 > num2{if(num1 == n||num2 == n)//达到目标状态{return true;}if(num1 < num2)swap(num1,num2);if(num1 == num2||num1 >= n + 101|| num2 >= 101)//两个数相等,则无最优解;第一个数超过n太多无解;第二个数太大会运行错误return false;if(!vis[num1][num2])//入队列{vis[num1][num2] = 1;tail++;q[tail].num1 = num1;q[tail].num2 = num2;q[tail].step = step;}return false;}int main(){scanf("%d",&n);head = tail = -1;add(1,0,0);//初始状态的两个数,num1 = 1,num2 = 0int num1,num2,step;int ans;while(head < tail){++head;num1 = q[head].num1,num2 = q[head].num2,step = q[head].step + 1;if(add(num1+num1,num2,step) || add(num1,num2+num2,step) || add(num1,num1+num2,step) || add(num2,num1+num2,step) || add(num1,num1+num1,step) || add(num2,num2+num2,step) || add(num1 - num2,num2,step) || add(num1,num1 - num2,step))//考虑所有保和运算的情况,全部入队{ans = step;break;}}printf("%d\n",ans);}


0 0
原创粉丝点击