考虑一排价值为v1,v2 .......,vn的n个硬币。我们通过轮流交替对抗对手。在每个回合中,玩家从行中选择第一个硬币或最后一个硬币,永久地移除它,并接收硬币的值。如果我们先行动,确定我们绝对可以获得的最大金额。
我的解决方案
由于我们先行,我们可以选择v1或v2,然后我们的对手可以从开始或从开始选择。因此,可能出现的四个子问题是。
(1,1),(1,2),(2,1),(2,2)
其中(1,1)表示我从开始选择[即] 1]和对手从开始选择[即1]。
(1,2)意味着我从开始选择但是对手拿起最后一个。
因此,如果M(i,j)
是我可以选择的最大值(i,j),那么将(i,j)表示为递归函数。
M(i,j) = Max{ Max{ M(i+2,j), M(i+1,j-1) } + vi, Max{ M(i+1,j-1), M(i,j-2) } + vj }
说明:当我有i..j元素时,我可以选择第一个[i + 1],然后我的对手可以选择第一个[i + 2]或最后一个[j- 1],我想在下一次选中时有最大值,因此第一个词在外部Max中。
第二个类似于上面的那个,即如果我选择最后一个[j-1],对手选择第一个[i + 1]或最后一个[j-2],我下次最大化它。
现在,我在书中看到递归为
M(i,j) = Max{ Min{ Same } + vi, Min{ Same } + vj }
现在,我为什么要在这里尽量减少。它不等于说我第一次选择最大化,但是第二次我必须选择最小化。
我做错了什么? 感谢。
答案 0 :(得分:2)
如果你想计算你肯定赢得的金额,你必须假设你的对手正试图最大化他/她自己的结果,这相当于最小化< / em>你的(因为你的收益总和总是等于v1 + ... + vn
)。如果你的对手总是出错(从他/她的角度来看)移动,那么你的公式计算是你能赢得的。
答案 1 :(得分:2)
如果硬币的数量n
是偶数,则第一个玩家可以保证自己最大值为v1 + v3 + ... + v(n-1)和v2 + v4 + ... + vn。找出哪个是最大值,然后取v1或vn。此后,仅分别取出原来处于奇数位置或甚至位置的硬币。这是可能的,因为无论第二个玩家做什么,当第一个玩家再次移动时,处于奇数位置和均匀位置的硬币都会暴露出来。
这是最好的第一个玩家能做到的吗?第一个玩家可以从&#34;赔率&#34;到&#34; evens&#34;在任何举动,取决于是否&#34;新的平衡&#34;大于或小于&#34;新赔率&#34;的总和。然后,第二个玩家的策略应该是保持切换的动机尽可能低,这意味着选择最大的硬币(第一个或最后一个位置)。由此产生的位置可能仍会诱惑第一个玩家切换?是的,正如我们在下面的游戏中看到的那样:
1 3 19 6 8 20
第一个玩家增加1 + 19 + 8 = 28和3 + 6 + 20 = 29.他可以通过选择平均值20来保证总分至少为29.结果是
1 3 19 6 8
为了减少第一个玩家从平均值转换到赔率并且比总得分29更好的诱惑,第二个玩家需要8个。
1 3 19 6
然而,诱惑仍然存在。事实上,赔率位置的总和是1 + 19 = 20,平均值的总和只有3 + 6 = 9,所以第一个玩家现在可以通过切换到赔率来做得更好,并且取1,即使6更大。
3 19 6
最好的第二个玩家可以选择6,第一个玩家获得19,第二个玩家获得3.总分:第一个玩家20 + 1 + 19 = 40,第二个玩家8 + 6 + 3 = 17。
似乎第一个玩家总能以这种方式获得超过第二名玩家。但是,我们仍然不知道这是否是第一个玩家的最佳策略。
另一方面,如果硬币数n是奇数,则上述分析中第一个玩家和第二个玩家的角色基本上是相反的。
现在的问题是,上面列出的贪婪策略真的是最佳的吗?我们可以通过检查二元决策树检查特定情况,其中第一个玩家获取第一个或最后一个硬币,然后第二个玩家获取剩余的第一个或最后一个硬币等。树中将有2^n
个叶子;可以计算每个叶子的分数,然后从叶子到根部工作,每个较高节点的值可以计算为两个孩子的最大值或两个孩子的最小值,具体取决于轮到谁。 / p>
它可以通过递归函数调用隐式构建,而不是显式构建树,这将节省所需的总内存,但不会节省时间。
如果有人以这种方式分析游戏并提出与我不同的最佳策略,我非常希望看到它。
答案 2 :(得分:0)
http://www.geeksforgeeks.org/dynamic-programming-set-31-optimal-strategy-for-a-game/
此页面对问题以及解决方案给出了非常明确的解释。它的结论是:
F(i, j) represents the maximum value the user can collect from i'th coin to j'th coin. F(i, j) = Max(Vi + min(F(i+2, j), F(i+1, j-1) ), Vj + min(F(i+1, j-1), F(i, j-2) )) Base Cases F(i, j) = Vi If j == i F(i, j) = max(Vi, Vj) If j == i+1