代码:
本题很明显要用记忆化搜索或者动态规划来求解,如果直接使用动态规划的话,我们要想清楚有哪些子状态需要存储。
首先一定要存储的是取到某一个位置时,已经得到的最大值或者后面能得到的最大值,但是光有位置是不够的,相同的位置有不同数量的堆可以取,所以我们还需存储当前的M值。
由于本题中的状态是从后往前递推的,如:假如最后只剩一堆,一定能算出来最佳方案,但是剩很多堆时不好算(依赖后面的状态)。所以我们选择从后往前递推。
func stoneGameII(piles []int) int {
prefixSum := make([]int, len(piles)+1)
for i, v := range piles {
prefixSum[i+1] = prefixSum[i] + v
}
type pair struct{ i, m int }
dp := map[pair]int{}
var f func(int, int) int
f = func(i int, m int) int {
if i == len(piles) {
return 0
}
if v, ok := dp[pair{i, m}]; ok {
return v
}
maxVal := math.MinInt
for x := 1; x <= 2*m; x++ {
if i+x > len(piles) {
break
}
maxVal = max(maxVal, prefixSum[i+x]-prefixSum[i]-f(i+x, max(m, x)))
}
dp[pair{i, m}] = maxVal
return maxVal
}
return (prefixSum[len(piles)] + f(0, 1)) / 2
}
func max(a, b int) int {
if b > a {
return b
}
return a
}