C++ 为什么我的子集求和方法不正确?
我是动态规划的新手,提出了解决子集和问题的方法(显然不正确)。我想知道为什么我的方法不正确。我特别好奇的是,基本的想法是否有效,或者我是否应该坚持使用子集和的正常方法 问题:给定一个数字数组,在数组中查找两个和相同的子集。与正常子集和问题相比,该问题略有改变 示例:C++ 为什么我的子集求和方法不正确?,c++,algorithm,dynamic-programming,C++,Algorithm,Dynamic Programming,我是动态规划的新手,提出了解决子集和问题的方法(显然不正确)。我想知道为什么我的方法不正确。我特别好奇的是,基本的想法是否有效,或者我是否应该坚持使用子集和的正常方法 问题:给定一个数字数组,在数组中查找两个和相同的子集。与正常子集和问题相比,该问题略有改变 示例:[1,5,5,9]可分为[1,9]和[5,5] 创意: 1 5 5 9 0 5 5 9 1 1 6 6 10 5 6 5 6 10 5 6 10 10 10 9 6 10 10 10
[1,5,5,9]
可分为[1,9]
和[5,5]
创意:
1 5 5 9
0 5 5 9
1 1 6 6 10
5 6 5 6 10
5 6 10 10 10
9 6 10 10 10
我不想(像往常一样)记录我取了哪些元素,哪些不取,而是想记录总数。其思想是在mem[i-1][j]
处(当前位置上方的一个位置)找到前面元素的总和。如果该值+当前值小于或等于总和的一半(本例中为20),则将当前值添加到总和中。否则,我们只取上一个值,忽略当前值
表中对角线上的元素将仅为其自身。我之所以这样做,是因为我会将相同的元素添加两次
在本例中,算法将在看到前10个时终止
实施:
1 5 5 9
0 5 5 9
1 1 6 6 10
5 6 5 6 10
5 6 10 10 10
9 6 10 10 10
bool有解决方案(std::vector&v){
const long sum=累加(v.begin(),v.end(),0);
长长记忆[v.size()+1][v.size()];
对于(int j=0;j 如果(new_sum除了非标准可变长度数组的问题之外(参见注释),您的概念就不能工作
缺陷是你的代码不考虑两个或多个小值必须跳过的可能性,以便找到一个解决方案。(也注意你所显示的代码和表不匹配。代码从不执行行<代码> 1 1 6 6 10 < /COD>)。
例如,考虑序列:
{4, 1, 6, 3, 4}
唯一有效的分区是{4,1,4}
和{6,3}
。此分区要求跳过两个分区的两个小条目,这是不受支持的
运行情况如下所示:
| 4 1 6 3 4
--+-------------------
4 |(0) 1 6 3 4
1 | 1 (1) 7 4 5
6 | 7 7 (7) 4 5
3 | 7 7 7 (7) 8
4 | 7 7 7 7 (8)
每个专栏都有自己的问题
(With 4)跳过前4个,因此它放弃了{4,1,4}
子集。因此它应该跳过1
,但由于它添加了它,因此此列将不起作用
(带1)添加了1
,因此它只能扩展到{4,1,4}
。因此它应该跳过6
,但最后添加了
(使用6)添加6
,因此它只能扩展到{4,1,4}
,然后添加1
,这是可以的。但是,由于它足够小(和4+1+3==8),所以它添加3
。但是3
它应该跳过它
(带3)添加代码接受的3+1+4
<9,但不会生成有效集
(使用4)添加4+1+3
>2N-1})。这将使成本为O(2N),其中N=v.size()。这比第一个算法要好,后者的成本为O(K),在这种情况下比O(2N)差得多。C++没有可变长度数组(某些编译器允许将其作为扩展)。代码长mem[v.size()+1][v.size()]
如果你传递一个适当大的向量,它也会炸毁堆栈。我在godbolt上尝试了一个1100元素的向量,但它出现了故障。这一点很好。我认为在更好的版本中,我会使用向量。这会更干净。尽管如此,godbold中的示例似乎是不正确的。所以问题是:跟踪和的想法是否有效?