【发布时间】:2012-05-17 15:33:27
【问题描述】:
考虑以下问题:
有 N 个硬币,编号从 1 到 N。
你看不到它们,但会得到关于它们的 M 个事实,形式如下:
struct Fact
{
set<int> positions
int num_heads
}
positions 标识硬币子集,num_heads 是该子集中正面硬币的数量。
考虑到这些 M 事实,您需要计算出可能出现正面的最大数量。
这个问题是 NP 完全的吗?如果是,减少量是多少?如果不是,什么是多项式时间解?
例如:
N = 5
M = 3
fact1 = { {1, 2}, 1 } // Either coin 1 or coin 2 is a head
fact2 = { {4}, 0 } // Coin 4 is a tail
fact3 = { {2, 4, 5}, 2 } // Out of coins 2, 4 and 5, two are heads
符合事实的最多人头的配置是:
T H H T H
所以答案是 3 个正面。
【问题讨论】:
-
也许我对您在此处提出的问题的思考时间不够长或不够认真,但您确定——首先——这个问题甚至是可以判定的吗?
-
@B.VB。这当然是可判定的:一个简单的指数算法是枚举所有 2^N 个可能的分配,并根据 M 个事实检查它们,跟踪最多人的解决方案。这是时间 O(N M 2^N)。
-
SAT 似乎应该有所减少,但我无法让它发挥作用。不过,我 80% 确定它在 NP 中。
-
查看我的答案,将 3-SAT 减少为硬币问题,表明它是 NP 难的。 NP-completeness 遵循多项式检查来验证解决方案。
标签: algorithm np-complete