解题报告:洛谷 P2737 [USACO4.1]麦香牛块Beef McNuggets

参考代码

const int LIM = 256 * 256 - 2 * 256 + 1;

int n;
int capacity[20];
bool available[LIM + 1];

void init()
{
	scanf("%d",&n);
	for (int i = 1;i <= n;++i) scanf("%d",&capacity[i]);
}

void work()
{
	available[0] = true;
	for (int i = 1;i <= n;++i)
		for (int j = capacity[i];j <= LIM;++j)
			available[j] = available[j] || available[j - capacity[i]];
	for (int i = LIM;i >= 0;--i)
	{
		if (i == 0 || (available[i] == false && i > 64769)) {printf("0"); break;}
		else if (available[i] == false) {printf("%d",i); break;}
	}
}

分析

  • 完全背包
  • 扩展欧几里德

题意:

给你 n n n个数 a 1 , a 2 ⋯ a n a_1,a_2\cdots a_n a1,a2an, 要你求最大的正整数 m m m使得方程 a 1 x 1 + a 2 x 2 + . . . + a n x n = m a_1x_1+a_2x_2+...+a_nx_n=m a1x1+a2x2+...+anxn=m无非负整数解. 题目数据满足 a x a_x ax为正整数且不大于 256 256 256, n ≤ 10 n≤10 n10

(via.https://www.luogu.org/blog/user21910/solution-p2737)

直接从1枚举到2 billion的背包容量显然会超时,有没有可以把这个“枚举上限”缩小的方法呢?

答案是:只需要将背包容量从1枚举到 25 6 2 − 2 ∗ 256 256^2 - 2 * 256 25622256即可。为什么?

你可能感兴趣的:(解题报告)