计算给定约束可能的最大总和

时间:2018-05-10 05:30:12

标签: c++11 subset dynamic-programming

所以,我在topcoder上找到了这个问题:

  

你的朋友卢卡斯给了你一个正整数序列S.

     

有一段时间,你们两个用S玩了一个简单的游戏:卢卡斯会选择一个   数字,你必须选择S的一些元素,使得总和   您选择的所有数字都是Lucas选择的数字。例如,   如果S = {2,1,2,7}且卢卡斯选择数字11,你会回答这个问题   2 + 2 + 7 = 11。

     

卢卡斯现在想通过选择数字X来欺骗你   将无效答案。例如,如果S = {2,1,2,7},则不是   可以选择S总和为6的元素。

     

给你int [] S.找到最小的正整数X.   不能作为S的一些(可能是所有)元素的总和获得。

     

约束:    - S将包含1到20个元素,包括1和20个元素。    - S的每个元素都在1到100,000之间,包括在内。

但是在编辑解决方案中已经写了:

  

如何找到最小的不可能的总和?好吧,我们可以尝试一下   遵循天真算法:首先尝试使用x = 1,如果不是这样的话   有效总和(使用上一节中的方法找到),然后我们   可以返回x,否则我们会增加x并再试一次,直到   我们找到的最小数字不是有效总和。

     

让我们找到迭代次数的上限,即数量   我们需要在找到结果之前尝试x的值。首先   所有,这个问题可能的最大总和是100000 * 20(全部   数字是最大的100000),这意味着100000 * 20 + 1会   不是一个不可能的价值。我们肯定最多需要2000001   步骤。

     

这个上界有多好?如果我们在20个中每个都有100000个   数字,1不是可能的总和。所以我们确实需要一个   在那种情况下迭代。如果我们希望1成为可能的总和,我们应该   在初始元素中有1。然后我们需要一个2(否则我们会   只需要2次迭代),然后通过添加找到43   1+2),然后857的数字可以通过添加一些来找到   在前两个的3个权力中,然后是16, 32, ...。事实证明   使用2的幂,我们可以轻松地进行需要很多的输入   迭代。凭借前两个的17个权力,我们可以掩盖到   第一个262143整数。这应该是一个很好的估计   最多的。 (我们不能在输入中使用2^18,小于   100000)。

     

最多262143次,我们需要查询数字x是否在该集合中   可能的总和。我们可以在这里使用布尔数组。看起来   但是,偶数O(log(n))数据结构应该足够快。

那么100000 * 20怎么可能给我们最大可能的金额呢?不会添加S的所有元素给我们最大的总和吗?。我似乎无法理解整个解决方案。如何使用子集?有人可以向我解释整个解决方案吗?我没有得到这背后的数学。我是动态编程的新手。

如果我问了太多问题,谢谢你,对不起。

1 个答案:

答案 0 :(得分:0)

"约束: - S将包含1到20个元素,包括1和20个元素。 - S的每个元素都在1到100,000之间,包括在内。"

这意味着S是一个整数数组。该数组可以包含1到20个元素,在本例中为整数。这些数字从1到100.000。 所以他正在考虑他可以从这个数组中获得的最大数量,这意味着20个数字,其中数字总是100.000

S = [100000,100000,100000等]