solution
跟上一道题目,Addition Chains挺像,甚至更加简单。也是iddfs。剪枝都差不多。就是这题有一个优化,当前这个数肯定是基于上一个数,然后进行加减。
#include<cstdio>
#include<algorithm>
#include<cstring>
#define fo(i,a,b) for (int (i)=(a);(i)<=(b);(i)++)
using namespace std;
const int N=1005;
int a[N],dep,n,m,p[N];
bool vis[N];
bool dfs(int x){
if (x-1==dep) return a[x-1]==n;
fo(i,0,x-1) {
a[x]=a[x-1]+a[i];
if (a[x]*p[dep-x]<n) continue;
if (dfs(x+1)) return 1;
a[x]=abs(a[x-1]-a[i]);
if (!a[x]) continue;
if (dfs(x+1)) return 1;
}
return 0;
}
int main(){
// freopen("data.in","r",stdin);
p[0]=1; fo(i,1,20) p[i]=p[i-1]*2;
while (scanf("%d",&n) && n){
m=n; a[0]=1; dep=0;
while (m){
m/=2; dep++;
}
dep--;
for (;;){
memset(vis,0,sizeof(vis));
if (dfs(1)) {
printf("%d\n",dep); break;
}
dep++;
}
}
return 0;
}