题干解析
剪枝
- ps.不懂请留言
然而并不一定能及时被看见 - 剪枝1:迭代搜索,层数超了就返回。
- 剪枝2:上限判断,如若剩余数的最大值加一起也小于n,返回。
- 剪枝3:搜索顺序,从大到小枚举。
- 剪枝4:如果当前值已经大于n,返回。
- 剪枝5~N:很多在循环条件中的小剪枝。
#include<bits/stdc++.h>
using namespace std;
int n,m,a[100001],u[100001],s[100001],ans;
inline int check(int t,int k){
for(int i=t;i>=t/2;i--)
if(u[k-a[i]]) return 0;
return 1;
}
inline void jqsh(int t,int k){
if(a[t]*(1<<(k-t+1))<n) return;
if(a[t]>n||t>k) return;
if(ans&&t>ans) return;
if(a[t]==n){
ans=t;
for(int i=1;i<=ans;i++) s[i]=a[i];
return;
}
for(int i=2*a[t];i>a[t];i--){
if(check(t,i)==0){
a[t+1]=i;u[i]=1;
jqsh(t+1,k);
a[t+1]=0;u[i]=0;
if(ans) return;
}
}
return;
}
int main(){
for(;;){
scanf("%d",&n);
if(!n) return 0;
a[1]=1;a[2]=2;ans=0;u[1]=u[2]=1;
if(n==1) printf("1");
else if(n==2) printf("1 2");
else{
for(int i=3;ans==0;i++)
jqsh(2,i);
for(int i=1;i<=ans;i++){
printf("%d ",s[i]);
s[i]=0;
}
}
printf("\n");
}
return 0;
}