石子游戏
https://leetcode-cn.com/problems/stone-game/
动态规划
DP 表定义:面对 [i, j]
之间的石头,先、后手的人分别能获得的最大石头数量。dp[i][j][0]
表示先手所得的最大石头,dp[i][j][1]
表示后手所得的最大石头。
由于石头只能从两端拿,如果先手拿了左边的,则石头变为 [i+1, j]
,且自己转换为后手,即自己的下一步能获得的最大石头 dp[i+1][j][1]
。同理,后手者等待先手拿完后,面对 [i+1, j]
这一堆石头,自己变成了先手,能获得的最大石头为 dp[i+1][j][0]
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| func stoneGame(piles []int) bool { n := len(piles) dp := make([][][]int, n) for i := range dp { dp[i] = make([][]int, n) for j := range dp[i] { dp[i][j] = make([]int, 2) } }
for i := 0; i < n; i++ { dp[i][i][0] = piles[i] }
for i := n-1; i >= 0; i-- { for j := i+1; j < n; j++ {
left := piles[i] + dp[i+1][j][1] right := piles[j] + dp[i][j-1][1]
if left > right { dp[i][j][0] = left dp[i][j][1] = dp[i+1][j][0] } else { dp[i][j][0] = right dp[i][j][1] = dp[i][j-1][0] } } }
return dp[0][n-1][0] > dp[0][n-1][1] }
|