【IDDFS】Power Calculus
题意:问最少经过多少次乘除法混合运算之后,可以用\(x\)计算得到\(x^n\)。可以使用中间值,但不能出现负次方幂。
思路:因为\(n<≤1000\),可以直接用一个数组记录得到的中间值。每一次用当前得到的数进行下一步计算,都遍历一次所有中间值,乘和除都试一遍就好了。
但如果单纯DFS,其中有一条路会无限乘下去,这显然是不行的。因此需要一个约束值\(maxh\),以及估算的边界\(maxh-cur\),如果当前指数的\(2^{maxh-cur}\)倍仍小于\(n\),说明答案在更深处,\(maxh\)小了,需要迭代加深。
注意\(maxh\)表示的就是最小的计算次数,最后答案就是它。
int n, maxh;
int rec[1010];
bool dfs(int x, int cur) {
//当前计算到的指数为x,中间已经算到了cur个指数
if ((x << maxh - cur) < n) return false;
//当前指数的2^(maxh-cur)倍也达不到n,说明答案在更深处
if (cur > maxh) return false;
//超过深度约束值,仍搜不到
rec[cur] = x;
if (x == n) return true;
//用之前算到过的指数乘/除都尝试一遍
for (int i = 0; i <= cur; i++) {
if (dfs(x + rec[i], cur + 1)) return true;
if (dfs(abs(x - rec[i]), cur + 1)) return true;
//注意题目要求不出现负指数
}
return false;
}
int main() {
while (cin >> n && n) {
maxh = 0;
memset(rec, 0, sizeof(rec));
while (!dfs(1, 0)) {
memset(rec, 0, sizeof(rec));
maxh++;
//清空数据,加大约束值,重新搜索
}
cout << maxh << endl;
}
return 0;
}