这题自己写了个暴力,发现过不去,看紫书才发现有个未被证明的结论:用最后一个得出的去做运算
AC代码
#include<bits/stdc++.h>
using namespace std;
int a[500];
int n;
int h(int d){
int maxsun=-1;
for(int i=0;i<=d;i++)maxsun=max(a[i],maxsun);
return maxsun;
}
bool dfs(int d,int maxd){
//cout<<d<<" "<<a[d]<<endl;
if(h(d)<<(maxd-d)<n)return 0;
if(a[d]==n)return 1;
for(int i=0;i<=d;i++){
a[d+1]=a[d]+a[i];
if(dfs(d+1,maxd))return 1;
a[d+1]=a[d]-a[i];
if(a[d+1]>0&&dfs(d+1,maxd))return 1;
}
return 0;
}
int main(){
while(scanf("%d",&n)==1&&n){
int maxd;
a[0]=1;
for( maxd=0;;maxd++){
if(dfs(0,maxd))break;
}
printf("%d\n",maxd);
}
return 0;
}
错误代码 T
#include<bits/stdc++.h>
using namespace std;
int a[500];
int vis[500];
int n;
int h(int d){
int maxsun=-1;
for(int i=0;i<=d;i++)maxsun=max(a[i],maxsun);
return maxsun;
}
bool dfs(int d,int maxd){
//cout<<d<<" "<<a[d]<<endl;
if(h(d)<<(maxd-d)<n)return 0;
if(a[d]==n)return 1;
for(int i=0;i<=d;i++){
for(int j=0;j<=d;j++){
if(vis[a[i]+a[j]]==-1||d<vis[a[i]+a[j]]){
int temp=vis[a[i]+a[j]];
vis[a[i]+a[j]]=d;
a[d+1]=a[i]+a[j];
if(dfs(d+1,maxd))return 1;
vis[a[i]+a[j]]=temp;
}
if((a[i]-a[j])>0&&(vis[a[i]-a[j]]==-1||d<vis[a[i]-a[j]])){
int temp=vis[a[i]-a[j]];
vis[a[i]-a[j]]=d;
a[d+1]=a[i]-a[j];
if(dfs(d+1,maxd))return 1;
vis[a[i]-a[j]]=temp;
}
}
}
return 0;
}
int main(){
while(scanf("%d",&n)==1){
memset(vis,-1,sizeof(vis));
int maxd;
vis[1]=0;
a[0]=1;
for( maxd=0;;maxd++){
if(dfs(0,maxd))break;
}
printf("%d\n",maxd);
}
return 0;
}