列表

详情


NC50244. Addition Chains

描述

乔治有一些同样长的小木棍,他把这些木棍随意砍成几段,直到每段的长都不超过50。现在,他想把小木棍拼接成原来的样子,但是却忘记了自己开始时有多少根木棍和它们的长度。给出每段小木棍的长度,编程帮他找出原始木棍的最小可能长度。

输入描述

第一行为一个单独的整数N表示砍过以后的小木棍的总数。第二行为N个用空格隔开的正整数,表示N根小木棍的长度。

输出描述

输出仅一行,表示要求的原始木棍的最小可能长度。

示例1

输入:

5
7
12
15
77
0

输出:

1 2 4 5
1 2 4 6 7
1 2 4 8 12
1 2 4 5 10 15
1 2 4 8 9 17 34 68 77

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 912ms, 内存消耗: 400K, 提交时间: 2020-02-26 12:24:36

#include<cstdio>
#include<cstring>
using namespace std;
int a[105],bo[105],ans[105];
int n,m;
bool check(int v,int x)
{
	for (int i=0; i<=x; ++i)
	if (v-a[i]>=0 && bo[v-a[i]]) return 1;
	return 0;
}
void dfs(int x)
{
	if (x>=m) return;
	if (a[x]==n) {
		if (x<m) m=x,memcpy(ans,a,sizeof(ans)); 		
		return;
	}
	for (int j=n; j>a[x]; --j)
	if (check(j,x)){
		a[x+1]=j;
		bo[j]=1;
		dfs(x+1);
		bo[j]=0;
	}
	return;
}
int main()
{
	bo[1]=1;
	a[0]=1;
	while (scanf("%d",&n),n){
		for (int i=2; i<=n; ++i) bo[i]=0;
		m=1e5;
		dfs(0);
		for (int i=0; i<=m; ++i) printf("%d ",ans[i]);
		printf("\n");
	}
}

上一题