funcstoneGameII(piles []int)int { n := len(piles) // 二维数组,记录当A拿第一堆时,第i堆被A拿的时候对应的M的最大石头数量 f := make([][]int, n) for i := range f { f[i] = make([]int, n+1) } // 从最后一堆开始往前循环 for i, s := n-1, 0; i >= 0; i-- { s += piles[i] // M 从1开始循环,直到 i/2+1,也就是假设可以一次性拿一半,M最大是已经拿了的一倍 for m := 1; m <= i/2+1; m++ { // 状态转移方程,可以全部都拿,就全部都拿 if i+m*2 >= n { f[i][m] = s } else { // 不能全部都拿 mn := math.MaxInt // 便利M,获取B拿最少的 for x := 1; x <= m*2; x++ { mn = min(mn, f[i+x][max(m, x)]) } // 剩下的就是自己最多的 f[i][m] = s - mn } } } return f[0][1] }
funcmin(a, b int)int { if b < a { return b } return a } funcmax(a, b int)int { if b > a { return b } return a }
// 例如有a,b,c // 只有两种情况,要么是加上a,然后计算dfs(b,c) // 要么就是回溯,不加上a,计算dfs(b,c) // 返回两者的最大值 var res int var flag bool tmpLetter := letter tmp := words[0] for i := 0; i < len(tmp); i++ { if tmpLetter[tmp[i]-'a'] <= 0 { flag = true break } tmpLetter[tmp[i]-'a']-- res += score[tmp[i]-'a'] }
if flag { // 此时a不满足,则直接下一个 return dfs(words[1:], letter, score) } // 此时a满足,结果只有两种情况,要么是算自己的最大值,要么是不算自己的最大值,两者选一个最大值返回 return max(dfs(words[1:], tmpLetter, score)+res, dfs(words[1:], letter, score)) }
funcmax(i, i2 int)int { if i > i2 { return i } return i2 }