将整数数组分解为具有精确总和的最大子数组

时间:2015-07-23 16:03:00

标签: arrays algorithm discrete-mathematics

如果我有像......这样的整数数组。

{3,5,5,6,6,6,6,6,6,7,7,8,8,8,9,9,9}

我想创建最多添加到40个子元素的子数组,每个元素只使用一次。只要没有使用所有重复,重复数字就可以了。

很容易找到最大数量的子阵列并找到40个子阵列,但问题是找到提供40的子阵列并且不会阻止40个其他子阵列形成。

我需要输出形成的子集。

这听起来与分区问题非常相似。

这个问题有名字吗?有人有解决方案吗?

2 个答案:

答案 0 :(得分:1)

可能效率不高但你可以做到以下几点 - 找到可以解决子集和问题的40的倍数,从40< =总和和最小值的最大倍数开始。然后,一旦找到总和为40的倍数的子集,就解决该子集的适当k分区问题。例如,如果40的倍数是120求解(如果可能的话)3分区问题,将其分成3组相等的大小。但请注意,在排除120的解决方案之前,仅仅确定总和为120的单个子集是不够的 - 您必须查看总和为120的所有子集,因为一个这样的子集可能具有可解决的3分区问题而另一个这样的子集却没有。

答案 1 :(得分:0)

您可以使用动态编程。让dp[j]- the max number of segments that sum to 40 s.t. no index of segments is larger than j。然后,您可以执行以下操作:

for(int i = 0; i < numbers.size(); i++)
    for(int j = i, sum = numbers[j]; j >= 0 && sum <= 40; j--, sum += numbers[j]) {
        if(sum == 40) {
            dp[i] = max(dp[i], j > 0 ? dp[j-1] : 0);
        }
    } 

int answer = 0;
for(int i = 0; i < dp.size(); i++)
    answer = max(answer, dp[i]);

我认为代码应该是不言自明的。