网址如下:
Power Calculus - UVA 1374 - Virtual Judge (vjudge.net)
用的迭代加深搜索做的
先上代码:
#include<cstdio>
#include<cmath>
const int maxn = 2001;
bool vis[maxn];
int n, ans, arr[maxn];
int _2[100]{1};
int fetch2_(int cur){
if(_2[cur]) return _2[cur];
return _2[cur] = fetch2_(cur - 1) * 2;
}
void dfs(int d, int maxd, int maxm){
if(arr[d - 1] == n) ans = maxd;
if(d > maxd || maxm * fetch2_(maxd - d + 1) < n) return;
//先加法延申
for(int i = 0; i < d; i++){
if(ans >= 0) return;
int nxt = arr[d - 1] + arr[i];
if(vis[nxt] || (maxm > n && nxt > n)) continue;
arr[d] = nxt; vis[nxt] = true;
dfs(d + 1, maxd, (maxm > nxt) ? maxm : nxt);
vis[nxt] = false;
}
//后减法延申
for(int i = 0; i < d; i++){
if(ans >= 0) return;
int nxt = arr[d - 1] - arr[i];
if(nxt <= 0 || vis[nxt]) continue;
arr[d] = nxt; vis[nxt] = true;
dfs(d + 1, maxd, maxm);
vis[nxt] = false;
}
}
int main(void)
{
vis[1] = true; arr[0] = 1;
while(scanf("%d", &n) == 1 && n){
ans = -1;
for(int maxd = 0; ans == -1; maxd++)
dfs(1, maxd, 1);
printf("%d\n", ans);
}
return 0;
}
简单来说就是每一次“位移”都是选择两个数进行加法或除法来得到新的数,初始的数组只有1,代表的是x^1
列出几个优化方法:
不产生重复的数
只需要有一个数大于n
当最大的数乘2^(maxd - d)所得到的数小于n的时候剪枝
加法不是任选两个数,而是尽可能选更大的数
限制减法的次数
猜想:每次使用新得到的数