题目链接
Addition Chains POJ2248
- 枚举过程中优先枚举大数+剪枝
- 按层数进行搜索,
- 剪枝
a[i]+a[j]<=a[x-1]
枚举过小直接break
a[i]+a[j]>n
枚举过大continue
bool v[]
标记
#include<iostream>
#include<cstring>
using namespace std;
int n,a[101],dep = 1;
bool v[101];
bool dfs(int x){
if(x>dep){
if(a[dep] == n)
return true;
else
return false;
}
memset(v,false,sizeof(v));
for(int i = x - 1; i >= 1; i--){
for(int j = i; j >= 1; j--){
if(a[i]+a[j]<=a[x-1])
break;
if(a[i]+a[j]>n)
continue;
if(a[i]+a[j]<=n&&!v[a[i]+a[j]]){
a[x] = a[i]+a[j];
v[a[x]] = 1;
if(dfs(x+1))
return true;
}
}
}
return false;
}
int main(){
while(cin>>n&&n){
if(n == 1){
cout<<1<<endl;
continue;
}
a[1] = 1;
for(dep = 2; ; dep++){
memset(v,0,sizeof(v));
if(dfs(2)) {
break;
}
}
for(int i = 1; i <= dep; i++){
cout << a[i] << ' ';
}
cout<<endl;
}
return 0;
}