假设我们有8个糖果袋。每个包包含糖果1,2,3,4,5,6,7,8
。
糖果必须在两个人之间分配,以便每个人收到相同数量的糖果。每个人收到的糖果袋数量无关紧要。
例如,{1,2,3,4,8}
和{5,6,7}
是一种可能性。另一种可能性是{3,4,5,6}
和{1,2,7,8}
。
必须计算可能性的总数。
我可以考虑使用强力算法来计算总和并检查是否相等。但解决方案对我来说并不好看。
我该如何处理这个问题?
答案 0 :(得分:1)
这是一个众所周知的问题:https://en.wikipedia.org/wiki/Partition_problem
答案 1 :(得分:1)
您可以通过注意总共36个糖果来减少您需要检查的可能性,因此每个人需要准确地收到18个糖果。您可以通过注意到任何人可以拥有的最多袋子数量为5来进一步减少它,因为没有6袋或更多袋子的组合,其总和<= 18个糖果,并且同样可以具有最少数量的袋子是3。
蛮力方法不需要很长时间来计算。这里我使用了一系列5个嵌套循环:
#include <stdio.h>
int main ()
{
int num_possibilities = 0;
int sum;
int a, b, c, d, e;
for (a = 1; a <= 8; a++) {
for (b = a + 1; b <= 8; b++) {
for (c = b + 1; c <= 8; c++) {
sum = a + b + c;
if (sum == 18) {
num_possibilities++;
printf ("%d %d %d\n", a, b, c);
continue;
}
for (d = c + 1; d <= 8; d++) {
sum = a + b + c + d;
if (sum == 18) {
num_possibilities++;
printf ("%d %d %d %d\n", a, b, c, d);
continue;
}
for (e = d + 1; e <= 8; e++) {
sum = a + b + c + d + e;
if (sum == 18) {
num_possibilities++;
printf ("%d %d %d %d %d\n", a, b, c, d, e);
continue;
}
}
}
}
}
}
printf ("Number of possibilities = %d", num_possibilities);
}
循环变量a
表示从8个包中选择的第一个包1中的糖果数。循环变量b
表示选择的第二个人员1中的糖果数量,依此类推。
由于我们只需计算人1在他所有行李中所拥有的糖果总数,我们可以在算法中完全忽略人2。
以上代码产生了14种不同组合的答案(我希望它是对的!)。