考虑以下问题:子集推断NP完全?
有编号为1到N
你不能看到他们ň硬币,但鉴于有关它们的形式的M个事实:
struct Fact
{
set<int> positions
int num_heads
}
positions
识别硬币的一个子集,并且num_heads
是该子集中硬币的头数。
鉴于这些M事实,您需要计算出可能的最大头数。
这个问题NP-complete?如果是,那么减少是多少?如果不是,什么是多项式时间解决方案?
例如:
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)。 – Dougal
SAT似乎应该有所减少,但我无法完成它的工作。不过,我有80%的确实是NP。 – Dougal