题目大意:给定数x和n,求x的n次方,只能用乘法和除法,算过的结果可以被利用。问最少算多少次就够了。n<=1000.
这一题等价于从数字1开始,用加减法,最少算多少次能得到数字n。
这一题为了方便,可以用IDDFS,每次指定递归深度,每次做dfs的时候不能超过这个深度。
同时可以使用估价函数:如果当前的值每次都乘2,一直打到指定深度,仍然不能达到n,停止用这个值。
代码如下:
#include<iostream>
#include<algorithm>
using namespace std;
int val[1010];
int pos,n;
bool ida(int now,int depth){ //从当前深度到指定深度
if(now>depth) return false;//如果当前深度大于指定深度,结束
if(val[pos]<<(depth-now)<n)//如果最快方式都不能到达n,结束
return false;
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;//当前深度加1,继续递归
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++){//从0开始指定深度,一直到当前指定深度可以求出n时,输出当前指定深度
val[pos=0]=1;//第一个数为1
if(ida(0,depth)) break;//每次都从第0层dfs到第depth层
}
cout<<depth<<endl;
}
return 0;
}