395.Coins in a Line II
1.Description(Medium)
There are n coins with different value in a line. Two players take turns to take one or two coins from left side until there are no more coins left. The player who take the coins with the most value wins.
Could you please decide the first player will win or lose?
Example
Given values array A =[1,2,2]
, returntrue
.
Given A =[1,2,4]
, returnfalse
.
2.Code
state : DP[i]表示从i到end能取到的最大value
function :
当我们走到i
时,有两种选择
取
values[i]
取
values[i] + values[i+1]
1.我们取了values[i]
,对手的选择有values[i+1]
或者values[i+1] + values[i+2]
剩下的最大总value分别为DP[i+2]
或DP[i+3]
, 对手也是理性的所以要让我们得到最小value
所以value1 = values[i] + min(DP[i+2], DP[i+3]).
2.我们取了values[i]
和values[i+1]
同理value2 = values[i] + values[i+1] + min(DP[i+3], DP[i+4])
最后
动态规划4要素
State:
dp[i] 现在还剩i个硬币,现在当前取硬币的人最后最多取硬币价值
Function:
i 是所有硬币数目
sum[i] 是后i个硬币的总和
dp[i] = sum[i]-min(dp[i-1], dp[i-2])
Intialize:
dp[0] = 0
dp[1] = coin[n-1]
dp[2] = coin[n-2] + coin[n-1]
Answer:
dp[n]
可以画一个树形图来解释:
也就是说,每次的剩余硬币价值最多值dp[i],是当前所有剩余i个硬币价值之和sum[i],减去下一手时对手所能拿到最多的硬币的价值,即dp[i] = sum[i] - min(dp[i - 1], dp[i - 2])
当我们处在i处时,我们有两种选择,拿一个还是拿两个硬币,我们现在分情况讨论:
当我们只拿一个硬币values[i]时,那么对手有两种选择,拿一个硬币values[i+1],或者拿两个硬币values[i+1] + values[i+2] a) 当对手只拿一个硬币values[i+1]时,我们只能从i+2到end之间来取硬币,所以我们能拿到的最大硬币数为dp[i+2] b) 当对手拿两个硬币values[i+1] + values[i+2]时,我们只能从i+3到end之间来取硬币,所以我们能拿到的最大硬币数为dp[i+3] 由于对手的目的是让我们拿较小的硬币,所以我们只能拿dp[i+2]和dp[i+3]中较小的一个,所以对于我们只拿一个硬币的情况,我们能拿到的最大钱数为values[i] + min(dp[i+2], dp[i+3])
当我们拿两个硬币values[i] + values[i + 1]时,那么对手有两种选择,拿一个硬币values[i+2],或者拿两个硬币values[i+2] + values[i+3] a) 当对手只拿一个硬币values[i+2]时,我们只能从i+3到end之间来取硬币,所以我们能拿到的最大硬币数为dp[i+3] b) 当对手拿两个硬币values[i+2] + values[i+3]时,我们只能从i+4到end之间来取硬币,所以我们能拿到的最大硬币数为dp[i+4] 由于对手的目的是让我们拿较小的硬币,所以我们只能拿dp[i+3]和dp[i+4]中较小的一个,所以对于我们只拿一个硬币的情况,我们能拿到的最大钱数为values[i] + values[i + 1] + min(dp[i+3], dp[i+4])
综上所述,递推式就有了 dp[i] = max(values[i] + min(dp[i+2], dp[i+3]), values[i] + values[i + 1] + min(dp[i+3], dp[i+4])) 这样当我们算出了dp[0],知道了第一个玩家能取出的最大钱数,我们只需要算出总钱数,然后就能计算出另一个玩家能取出的钱数,二者比较就知道第一个玩家能否赢了s
Last updated
Was this helpful?