Addition Chains

link

迭代加深。顺便说一句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;
}
posted @ 2022-07-05 16:56  Feyn618  阅读(21)  评论(0编辑  收藏  举报