所以,我在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次迭代),然后通过添加找到4
(3
1+2
),然后8
(5
到7
的数字可以通过添加一些来找到 在前两个的3个权力中,然后是16, 32, ...
。事实证明 使用2的幂,我们可以轻松地进行需要很多的输入 迭代。凭借前两个的17个权力,我们可以掩盖到 第一个262143整数。这应该是一个很好的估计 最多的。 (我们不能在输入中使用2^18
,小于 100000)。最多262143次,我们需要查询数字
x
是否在该集合中 可能的总和。我们可以在这里使用布尔数组。看起来 但是,偶数O(log(n))
数据结构应该足够快。
那么100000 * 20怎么可能给我们最大可能的金额呢?不会添加S的所有元素给我们最大的总和吗?。我似乎无法理解整个解决方案。如何使用子集?有人可以向我解释整个解决方案吗?我没有得到这背后的数学。我是动态编程的新手。
如果我问了太多问题,谢谢你,对不起。
答案 0 :(得分:0)
"约束: - S将包含1到20个元素,包括1和20个元素。 - S的每个元素都在1到100,000之间,包括在内。"
这意味着S是一个整数数组。该数组可以包含1到20个元素,在本例中为整数。这些数字从1到100.000。 所以他正在考虑他可以从这个数组中获得的最大数量,这意味着20个数字,其中数字总是100.000
S = [100000,100000,100000等]