题意:给出x和正整数n,问最少需要几次乘除法 可以得到n = x^m
思路:其实是关于指数的操作,即从1到m最少的步数。我们可以先确定最少步数m,然后进行迭代,迭代的过程也就是判断通过相加减所得到的数可以在m次操作中等于n,如果符合,m即为最小步数,如果不符合,m++,进行下一次迭代。迭代过程中要注意剪枝,即剩余的次数如果每次都是取最大值相加还是比n小的话,就直接跳出。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
const int MAXN = 1005;
using namespace std;
int arr[MAXN];
int n, depth, num;
void init() {
depth = 0;
int temp = 1;
while (n > temp) {
temp = temp * 2;
depth++;
}
}
int dfs(int cur, int d) {
if (d >= depth) {
if (cur == n)
return true;
return false;
}
for (int i = num - 1; i >= 0; i--) {
int Max = 0;
for (int j = 0; j < num; j++)
Max = max(Max, arr[j]);
if ((cur + Max) << (depth - d - 1) < n)
return false;
arr[num++] = cur + arr[i];
if (dfs(cur + arr[i], d + 1))
return true;
num--;
arr[num++] = cur - arr[i];
if (dfs(cur - arr[i], d + 1))
return true;
num--;
}
return false;
}
int main() {
while (scanf("%d", &n) && n) {
if (n == 1) {
printf("0\n");
continue;
}
init();
while (1) {
memset(arr, 0, sizeof(arr));
arr[0] = num = 1;
if (dfs(1, 0))
break;
depth++;
}
printf("%d\n", depth);
}
return 0;
}