选择N个包的M,因此总和是K的最小倍数

时间:2011-11-27 10:59:06

标签: algorithm

我在Codechef上看到了这个程序。 每包含一些糖果的N个包。 (例如:1st包含10,2nd包含4,依此类推) 我们必须从中精确选择M个包(M <= N),使得总糖果可被K整除。 如果有多个解决方案,则输出糖果数量最少的解决方案。

我认为它类似于Subset Sum问题,但那是NP难的。因此需要指数时间。

我不想要这个程序的完整解决方案。一种算法将是值得赞赏的。从2天开始思考但无法得到正确的逻辑。

1≤M≤N≤50000,1≤K≤20 每个包中的糖果数量[1,10 ^ 9]

2 个答案:

答案 0 :(得分:1)

packets包含原始数据包。

k分区为p = 1, 2, ..., m个数字>= 1< k的总和(有O(2^k)个此类分区)。对于每个分区,迭代packets并添加其余模k是分区元素之一的数字,然后从分区中删除该元素。保持最小总和,并更新全局最小值。请注意,如果m > p,您还必须拥有m - p个零。

您可能认为这是O(2^k * n)并且速度太慢,但如果您保留packets,则实际上不必为每个分区迭代num[i] = how many numbers have packets[i] % k == i数组,在这种情况下它变成O(2^k + n)。为了处理最小总和要求,您可以保留num[i] = the list of the numbers that have packets[i] % k == i,这将允许您始终为有效分区选择最小数字。

答案 1 :(得分:0)

再次查看http://en.wikipedia.org/wiki/Subset_sum_problem#Pseudo-polynomial_time_dynamic_programming_solution并注意K相对较小。此外,虽然N可以很大,但是所有你关心的涉及N的总和都是答案mod K.所以有一个动态的编程解决方案潜伏在这里,在每一步你有K个可能的值mod K,你保持追踪目前可以达到的这些值。