题目描述:
你现在有x^1,每动一步可以用当前存在的x^a和x^b获得x^(a+b)或x^(abs(a-b))。给出n(n<=1000),求最少多少步能得到x^n。
题解:
IDDFS。枚举步数,然后dfs+剪枝。
剪枝:
1.目标高于上限时减掉;
2.当前存在两个>n或以上时减掉。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 1050 int n,lim; int a[N]={1}; int vis[N]={0,1}; bool fg=0; void dfs(int dep,int mx) { if(a[dep-1]==n)fg=1; if(fg)return ; if(dep>lim)return ; if(mx*(1<<(lim-dep+1))<n)return ; for(int i=0;i<dep;i++) { int x = a[i]+a[dep-1]; if(mx<n||x<n) { if(!vis[x]) { vis[x]=1; a[dep]=x; dfs(dep+1,max(mx,x)); vis[x]=0; } } x=a[i]-a[dep-1]; if(x<0)x=-x; if(mx>n&&x>n)continue; if(!vis[x]&&x) { vis[x]=1; a[dep]=x; dfs(dep+1,max(mx,x)); vis[x]=0; } } } int main() { while(scanf("%d",&n)>0) { fg=0; if(!n)break; if(n==1) { printf("0 "); continue; } for(lim=1;;lim++) { dfs(1,1); if(fg) { printf("%d ",lim); break; } } } return 0; }