题意:给定数x和n,求x的n次方,只能用乘法和除法,算过的过程可以被利用。问最少多少次就够了。
(输入只有n,n<=1000)
这一题等价与从数字1开始,用加减法,最少多少次得到n。

思路:用IDDFS,并用估价函数进行剪枝;
(1)IDDFS:指定递归深度,每一次做递归时不超过这个深度,(这个深度得到的结果一定最优,否则在上一个深度就已经结束搜索了,所以一定是最深时才得到n)
(2)估价函数:如果当前的值用最快的方式(连续乘2,倍增)都不能到达(大于等于)n,停止这个值继续DFS(因为当前认为depth步是最优的,而倍增(depth-now)次挨都挨不到n,这个值就没必要了)
(3)下一个数=上一个数与前面所有的数相加,之所以这样,我个人认为有时存在几个连续的数倍增多次(到达最深时)都是大于或等于n的,可能加上不是最大的数后倍增多次会恰好等于n。(相减的应该差不多)
代码:

#include<iostream>
#include<cmath>
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;
}

(一天都没搞懂,求助钟涛大佬,大佬一下就思路通透了,tql)