假设有一行 x 箱子装满了小饰品(随机数量),在视线范围内(你可以看到每个箱子里有多少小装饰品)。现在有两名球员可以轮到他们从任何一端挑选一个垃圾箱。他们不能放弃转机。想出一个让玩家获得最大数量小饰品的策略。
x 是偶数。
这是一个完整的问题吗?它类似于布尔SAT吗?
答案 0 :(得分:5)
不,它可以通过O(x^2)
中的动态编程轻松解决。看看问题10 here。
答案 1 :(得分:5)
这是一个非常简单的问题,并不是NP完整的。 这里是算法的简短描述,它基于动态编程。
可以[i] - 存储小饰品数量的数组 F [i,j] - 如果只有从i到j的罐头可用,则确定什么是最佳移动的阵列。 0表示从左侧取,1表示从右侧取 G [i,j] - 存储移动'良好'的数组。
for (i=1 to n) F[i,i] = 0
for (i=1 to n) G[i,i] = Can[i]
for (i=1 to n-1)
for (j=1 to n-i)
tmp1 = Can[j] - G[j+1,j+i]
tmp2 = Can[j+i] - G[j,j+i-1]
if (tmp1>tmp2)
{
F[j,j+i] = 0;
G[j,j+i] = tmp1;
}
else
{
F[j,j+1] = 1;
G[j,j+i] = tmp2;
}
很抱歉没有评论,但如果您阅读了一些有关动态编程的文章,您将毫无问题地获得它。
答案 2 :(得分:0)
这个问题对于alpha-beta-pruning来说似乎是完美的,因为很容易得出你的点的下限。假设玩家面对偶数个箱子。然后,他可以通过某种方式进行游戏,以便在偶数或所有奇数位置上获得所有垃圾箱:
假设我们有1 0 1 0 1 0,那么他可以拿左边的1,无论对手做什么,他只是继续拿起1。
因此,容易计算的下限是偶数位置上所有二进制位总和的最大值以及奇数位置上所有二进制位的总和。
对于“奇数”玩家,你可以得到(长度+ 1)/ 2最小值的总和,这不是“偶数”玩家的界限,但也很容易计算。 / p>
我认为对于这些界限,搜索树对于实际应用来说将是稀疏的(我猜你总能找到这种类型问题的“病态”反例),所以解决方案应该非常快。
答案 3 :(得分:0)
很明显,第一个玩家有一个平局/胜利策略。他所要做的就是检查奇数位置分档或偶数位置分档是否有更大的总分,然后他可以很容易地发挥,以迫使对手拿起“失败”平价的分档。
例如:
2,6,11,4,7,3
这里奇数位置更好(20对13),所以玩家1应该选择2.然后玩家2必须选择6或3,它们处于偶数位置。如果选择3,则选手1应选择7,依此类推。实际上,玩家1应该总是选择他的对手选择的位置旁边的位置,并保证平局或胜利。