Addition Chains
迭代加深。顺便说一句UVA的评测速度比想象中快一点。
还是一样的,首先考虑限制序列长度(观察样例感觉最后的答案应该是log级别的,枚举是可以枚举的),也就是迭代加深部分。另一部分就是估价函数,其实这里甚至不需要一个函数来进行。由于序列递增,所以每个元素不可能比它前面的元素的两倍更大,所以当前元素乘上2的剩下机会数次幂还达不到m的标准时,这一支一定是不合法的,于是就可以达到剪枝的目的(感觉挺像A星搜索的)。后面的剪枝是很重要的,不加就会0分。UVA的题挺不错的,至少很少有CF那种胡乱评级的情况。
#include<bits/stdc++.h>
//#define feyn
#define int long long
const int N=10010;
using namespace std;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
int m,limit,a[N];
bool ok;
void dfs(int wh){
if(wh==limit){if(a[wh]==m)ok=true;return;}
if(ok||(a[wh]*(1ll<<limit-wh+1)<m))return;
for(int i=1;i<=wh;i++){
for(int j=i;j<=wh;j++){
if(ok)return;
a[wh+1]=a[i]+a[j];
dfs(wh+1);
}
}
}
void solve(){
if(m==1){
printf("1\n");
return;
}
ok=false,limit=1;
a[1]=1;
while(ok==false){
dfs(1);
if(ok){
for(int i=1;i<=limit;i++){
printf("%lld",a[i]);
putchar(i==limit?'\n':' ');
}
}
limit++;
}
}
signed main(){
#ifdef feyn
freopen("in.txt","r",stdin);
#endif
read(m);
while(m){
solve();
read(m);
}
return 0;
}
一如既往,万事胜意