又是IDA*,A*的剪枝依然是效率的保障。
大致思路:从数字1开始,每次用它对所有已经得到的数字进行加/减,然后再用得到的新数字重复这个动作。当加/减的次数超过最大限度时停止,然后回溯。
Run Time: 0.665s
#define UVa "LT7-13.1374.cpp"
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
//Global Variables.
int vis[100000];
int arr[100000];
int n;
/////
int dfs(int d, int maxd, int u) {
if(d == maxd) {
if(u == n) {
printf("%d\n", d-1);
return 1;
}
return 0;
}
else {
if((u<<(maxd-d)) < n) return 0;
for(int i = 0; i < d; i ++) {
int v = u + arr[i];
if(!vis[v]) {
vis[v] = 1;
arr[d] = v;
if(dfs(d+1, maxd, v)) return 1;
vis[v] = 0;
}
v = abs(u-arr[i]);
if(!vis[v]) {
vis[v] = 1;
arr[d] = v;
if(dfs(d+1, maxd, v)) return 1;
vis[v] = 0;
}
}
}
return 0;
}
int main() {
while(scanf("%d", &n) && n) {
memset(vis, 0, sizeof(vis));
memset(arr, -1, sizeof(arr));
arr[0] = 1;
for(int maxd = 1; ; maxd ++)
if(dfs(1, maxd, 1)) break;
}
return 0;
}