什么其他人说的是真的:
这个问题是NP完全问题。简单的减少是通常的子集和。只有在联合(-B)的非空子集合为零时,才能通过注意到A的一个子集与B的子集(不是都为空)进行显示。
此问题仅弱NP完全,因为它是多项式在数字参与的规模,但推测是在其对数指数。这意味着这个问题比名词“NP-complete”所暗示的更容易。
您应该使用动态编程。
那么我对这个讨论有什么贡献?那么,代码(在Perl):
@a = qw(4 5 9 10 1);
@b = qw(21 7 -4 180);
%a = sums(@a);
%b = sums(@b);
for $m (keys %a) {
next unless exists $b{$m};
next if $m == 0 and (@{$a{0}} == 0 or @{$b{0}} == 0);
print "sum(@{$a{$m}}) = sum(@{$b{$m}})\n";
}
sub sums {
my(@a) = @_;
my($a, %a, %b);
%a = (0 => []);
while(@a) {
%b = %a;
$a = shift @a;
for my $m (keys %a) {
$b{$m+$a} = [@{$a{$m}},$a];
}
%a = %b;
}
return %a;
}
它打印
sum(4 5 9 10) = sum(21 7)
sum(4 9 10 1) = sum(21 7 -4)
所以,值得注意的是,有不止一个解决方案,在您的原始问题的作品!
编辑:用户itzy正确地指出,这种解决方案是错误的,更糟的是,以多种方式!我对此非常抱歉,我希望在上面的新代码中解决这些问题。尽管如此,仍然存在一个问题,即对于任何特定的子集和,它只打印出其中一个可能的解决方案。与以前的直接错误问题不同,我将其归类为有意限制。祝你好运,并提防错误!
嗨burningmonk。回应刚刚删除的问题:http://iancooper.brinkster.net/Frontpage.aspx是伦敦.NET用户组。它是Google老兄的第一个结果! – Nobody 2010-08-08 21:32:49