找出平等分配的可能性数量

时间:2015-10-30 05:38:35

标签: algorithm

假设我们有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}

必须计算可能性的总数。

我可以考虑使用强力算法来计算总和并检查是否相等。但解决方案对我来说并不好看。

我该如何处理这个问题?

2 个答案:

答案 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种不同组合的答案(我希望它是对的!)。