一、内容
题意: 给定一个n, 问最少多少步能够从x1凑成xn,可以进行2种操作,乘以或者除以以前获得过得xi 。
二、思路
- 由于1000以内的数最多10多步就能够凑出结果,所以考虑用迭代加深搜索。从0开始进行枚举,若找到一个结果返回
- 剪枝:判断一个数后面能不能凑出, 假设每次都乘以得出的数,那么就是 1 <<(limit - h) 已经的出的x的系数*,若最大的数也不能大于n,那么必定不符合要求。
三、代码
#include <cstdio>
#include <cstring>
int n, num[105], ok; //num数组记录每个x^i 对应的值
void dfs(int limit, int h, int x) {
if (ok) return;
num[h] = x;
if ((1 << (limit - h)) * x < n) return; //可行性剪枝
if (h == limit) {
//检查是否能够凑出
if (x == n) ok = true;
return;
}
for (int i = h; i >= 0; i--) {
dfs(limit, h + 1, x + num[i]);
dfs(limit, h + 1, x - num[i]);
}
}
int main() {
while (scanf("%d", &n), n) {
ok = 0;
memset(num, 0, sizeof(num));
for (int i = 0; ; i++) {
dfs(i, 0, 1);
if (ok) {
printf("%d\n", i);
break;
}
}
}
return 0;
}