这应该是除了打表以外最快的了,只有130ms。
今天做完这道题才真真了解一点什么叫IDA*,IDA*是有深度限制的深搜,本题恰好然求解的是操作的步数也就是搜索的深度,剪枝的条件是最大数*2^(maxd-d) < n,这说明这条路永远无法到达,所以要剪掉。
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <cmath>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long LL;
const int inf = 0x3f3f3f3f;
using namespace std;
int maxd; // 深度上限
int n; // 目标
int res[20]; // 集合,记录之前的数
bool dfs(int d, int maxn) {
if (d == maxd) return res[d-1]==n;
if (maxn<<(maxd-d) < n) return false;
for(int i = d-1; i >= 0; i--) {
int v1 = res[d-1]+res[i];
int v2 = res[d-1]-res[i];
res[d] = v1;
if(dfs(d+1, max(v1, maxn))) return true;
if (v2 <= 0) continue;
res[d] = v2;
if(dfs(d+1, max(v2, maxn))) return true;
}
return false;
}
int main() {
//freopen("input.txt", "r", stdin);
//freopen("output.txt", "w", stdout);
while(~scanf("%d", &n) && n) {
maxd = 1;
res[0]=1;
while(!dfs(1 , 1)) {
maxd++;
}
printf("%d\n", maxd-1);
}
return 0;
}