2023-07-05:爱丽丝和鲍勃继续他们的石子游戏

许多堆石子 排成一行,每堆都有正整数颗石子 piles[i]

游戏以谁手中的石子最多来决出胜负。

爱丽丝和鲍勃轮流进行,爱丽丝先开始。最初,M = 1。

在每个玩家的回合中,该玩家可以拿走剩下的 前 X 堆的所有石子,其中 1 <= X <= 2M

然后,令 M = max(M, X)。

游戏一直持续到所有石子都被拿走。

假设爱丽丝和鲍勃都发挥出最佳水平W

返回爱丽丝可以得到的最大数量的石头。

输入:piles = [2,7,9,4,4]。

输出:10。

答案2023-07-05:

1.算法 stoneGameII1:暴力方法

  • 首先定义函数 stoneGameII1,接收一个石子堆的切片 piles 作为参数,并返回爱丽丝可以得到的最大数量的石头。

  • 在函数 stoneGameII1 中调用函数 first1,并传入初始参数 piles、index=0(表示当前石子堆的索引)、m=1(表示当前的 M 值)。

  • 函数 first1 的作用是计算爱丽丝在当前石子堆的状态下的最优解。如果当前石子堆的索引达到了最后一个位置(即 index == len(piles)),则返回 0(石子已经全部取完)。

  • 否则,初始化变量 best = 0(当前的最优解)和 pre = 0(当前已经取走的石子数量)。

  • 开始一个循环,从当前索引开始遍历石子堆(i = index),并且用变量 j 记录当前取走的石子堆的数量(初始值为 1)。

  • 在循环中,更新变量 pre = pre + piles[i],即计算当前的已取走的石子数量。

  • 然后,根据当前的石子堆状态以及剩余可取的石子堆的数量(int(math.Max(float64(j), float64(m)))),调用函数 second1,并传入相应的参数,计算爱丽丝在下一轮的最优解。

  • 更新变量 best = int(math.Max(float64(best), float64(pre+second1(piles, i+1, int(math.Max(float64(j), float64(m))))))),即取当前轮最优解和已取走的石子数量之和的较大值作为当前的最优解。

  • 循环结束后,返回变量 best。

函数 second1 的作用是计算鲍勃在当前石子堆的状态下的最优解,其过程与函数 first1 类似。

  • 首先判断是否遍历到了最后一个石子堆,如果是,则返回 0(石子已全部取走)。
  • 否则,初始化变量 worse = math.MaxInt64(当前的最差解)。
  • 开始一个循环,从当前索引开始遍历石子堆,并用变量 j 记录当前取走的石子堆的数量(初始值为 1)。
  • 在循环中,更新变量 worse = int(math.Min(float64(worse), float64(first1(piles, i+1, int(math.Max(float64(j), float64(m))))))),即取当前轮最差解和已取走的石子数量之和的较小值作为当前的最差解。
  • 循环结束后,返回变量 worse。

2.算法 stoneGameII2:记忆化搜索

  • 首先定义函数 stoneGameII2,接收一个石子堆的切片 piles 作为参数,并返回爱丽丝可以得到的最大数量的石头。

  • 在函数 stoneGameII2 中,首先初始化变量 n 为石子堆的数量,创建两个二维切片 f 和 s,用于存储记忆化搜索的结果。

  • 利用循环,初始化 f 和 s 的值为 -1。

  • 调用函数 first2,并传入初始参数 piles、index=0(表示当前石子堆的索引)、m=1(表示当前的 M 值)、f 和 s。

  • 函数 first2 的作用是计算爱丽丝在当前石子堆的状态下的最优解,其过程类似函数 first1,但加入了记忆化搜索的机制。

  • 首先判断是否已经计算过该状态的结果,如果是,则直接返回存储的结果 f[index][m]。

  • 否则,继续计算最优解。

  • 在计算过程中,每一轮的最优解都会存储在 f[index][m],以避免重复计算。

  • 在循环中,需要调用函数 second2,传入相应的参数,计算鲍勃在当前石子堆的状态下的最优解,并存储在 s[i+1][int(math.Min(float64(len(piles)), float64(math.Max(float64(j), float64(m)))))] 中。

  • 循环结束后,将最优解保存到 f[index][m] 中,并返回最优解。

函数 second2 的作用是计算鲍勃在当前石子堆的状态下的最优解,与函数 second1 类似,但加入了记忆化搜索的机制。

  • 首先判断是否已经计算过该状态的结果,如果是,则直接返回存储的结果 s[index][m]。

  • 否则,继续计算最优解。

  • 在计算过程中,每一轮的最优解都会存储在 s[index][m],以避免重复计算。

  • 循环结束后,将最优解保存到 s[index][m] 中,并返回最优解。

3.算法 stoneGameII3:严格位置依赖的动态规划,一张表的版本

  • 首先定义函数 stoneGameII3,接收一个石子堆的切片 piles 作为参数,并返回爱丽丝可以得到的最大数量的石头。

  • 在函数 stoneGameII3 中,首先初始化变量 n 为石子堆的数量,创建两个二维切片 f 和 s,表示爱丽丝和鲍勃在每个石子堆的状态下的最优解。

  • 利用循环,初始化 f 和 s 的值为 0。

  • 初始化变量 sum = 0,用于记录累计的石子数。

  • 从最后一个石子堆开始循环,更新变量 sum = sum + piles[index],即计算当前的累计石子数。

  • 在循环中,根据动态规划的思想,计算爱丽丝和鲍勃的最优解。

  • 首先计算爱丽丝在当前石子堆状态下的最优解。

  • 声明变量 best = 0,表示当前的最优解。

  • 声明变量 pre = 0,表示当前已经取走的石子数量。

  • 在循环中,用变量 j 记录当前取走的石子堆的数量(初始值为 1)。

  • 在循环中,更新变量 pre = pre + piles[i],即计算当前的已取走的石子数量。

  • 根据当前的石子堆状态以及剩余可取的石子堆的数量(int(math.Min(float64(len(piles)), float64(math.Max(float64(j), float64(m)))))),计算爱丽丝在下一轮的最优解 s[i+1][int(math.Min(float64(len(piles)), float64(math.Max(float64(j), float64(m)))))]。

  • 更新变量 best = int(math.Max(float64(best), float64(pre+s[i+1][int(math.Min(float64(len(piles)), float64(math.Max(float64(j), float64(m)))))]))),取当前轮最优解和已取走的石子数量之和的较大值作为当前的最优解。

  • 计算鲍勃在当前石子堆状态下的最优解。

  • 声明变量 worse = math.MaxInt64,表示当前的最差解。

  • 在循环中,用变量 j 记录当前取走的石子堆的数量(初始值为 1)。

  • 在循环中,更新变量 worse = int(math.Min(float64(worse), float64(f[i+1][int(math.Min(float64(len(piles)), float64(math.Max(float64(j), float64(m)))))]))),取当前轮最差解和已取走的石子数量之和的较小值作为当前的最差解。

  • 循环结束后,更新 f[index][m] = best 和 s[index][m] = worse。

  • 返回 f[0][1],即爱丽丝在初始状态下的最优解。

4.算法 stoneGameII4:严格位置依赖的动态规划

  • 首先定义函数 stoneGameII4,接收一个石子堆的切片 piles 作为参数,并返回爱丽丝可以得到的最大数量的石头。

  • 在函数 stoneGameII4 中,首先初始化变量 n 为石子堆的数量,创建一个二维切片 dp,用于存储动态规划的结果。

  • 利用循环,初始化 dp 的值为 0。

  • 初始化变量 sum = 0,用于记录累计的石子数。

  • 从最后一个石子堆开始循环,更新变量 sum = sum + piles[i],即计算当前的累计石子数。

  • 在循环中,根据动态规划的思想,计算爱丽丝的最优。

stoneGameII1的时间复杂度为$O(2^n)$,空间复杂度为$O(n)$。

stoneGameII2的时间复杂度为$O(n3)$,空间复杂度为$O(n2)$。

stoneGameII3的时间复杂度为$O(n3)$,空间复杂度为$O(n2)$。

stoneGameII4的时间复杂度为$O(n^2)$,空间复杂度为$O(n)$。

go完整代码如下:

package main

import (
"fmt"
"math"
) // 暴力方法
func stoneGameII1(piles []int) int {
return first1(piles, 0, 1)
} func first1(piles []int, index, m int) int {
if index == len(piles) {
return 0
}
best := 0
pre := 0
for i, j := index, 1; i < len(piles) && j <= 2*m; i, j = i+1, j+1 {
pre += piles[i]
best = int(math.Max(float64(best), float64(pre+second1(piles, i+1, int(math.Max(float64(j), float64(m)))))))
}
return best
} func second1(piles []int, index, m int) int {
if index == len(piles) {
return 0
}
worse := math.MaxInt64
for i, j := index, 1; i < len(piles) && j <= 2*m; i, j = i+1, j+1 {
worse = int(math.Min(float64(worse), float64(first1(piles, i+1, int(math.Max(float64(j), float64(m)))))))
}
return worse
} // 记忆化搜索
func stoneGameII2(piles []int) int {
n := len(piles)
f := make([][]int, n)
s := make([][]int, n)
for i := 0; i < n; i++ {
f[i] = make([]int, n+1)
s[i] = make([]int, n+1)
for j := 0; j <= n; j++ {
f[i][j] = -1
s[i][j] = -1
}
}
return first2(piles, 0, 1, f, s)
} func first2(piles []int, index, m int, f, s [][]int) int {
if index == len(piles) {
return 0
}
if f[index][m] != -1 {
return f[index][m]
}
best := 0
pre := 0
for i, j := index, 1; i < len(piles) && j <= 2*m; i, j = i+1, j+1 {
pre += piles[i]
best = int(math.Max(float64(best), float64(pre+second2(piles, i+1, int(math.Min(float64(len(piles)), float64(math.Max(float64(j), float64(m))))), f, s))))
}
f[index][m] = best
return best
} func second2(piles []int, index, m int, f, s [][]int) int {
if index == len(piles) {
return 0
}
if s[index][m] != -1 {
return s[index][m]
}
worse := math.MaxInt64
for i, j := index, 1; i < len(piles) && j <= 2*m; i, j = i+1, j+1 {
worse = int(math.Min(float64(worse), float64(first2(piles, i+1, int(math.Min(float64(len(piles)), float64(math.Max(float64(j), float64(m))))), f, s))))
}
s[index][m] = worse
return worse
} // 严格位置依赖的动态规划,一张表的版本
func stoneGameII3(piles []int) int {
n := len(piles)
f := make([][]int, n+1)
s := make([][]int, n+1)
for i := 0; i <= n; i++ {
f[i] = make([]int, n+1)
s[i] = make([]int, n+1)
}
sum := 0
for index := n - 1; index >= 0; index-- {
sum += piles[index]
for m := 1; m <= n; m++ {
best := 0
pre := 0
for i, j := index, 1; i < len(piles) && j <= 2*m; i, j = i+1, j+1 {
pre += piles[i]
best = int(math.Max(float64(best), float64(pre+s[i+1][int(math.Min(float64(n), float64(math.Max(float64(j), float64(m)))))])))
}
f[index][m] = best
worse := math.MaxInt64
for i, j := index, 1; i < len(piles) && j <= 2*m; i, j = i+1, j+1 {
worse = int(math.Min(float64(worse), float64(f[i+1][int(math.Min(float64(n), float64(math.Max(float64(j), float64(m)))))])))
}
s[index][m] = worse
}
}
return f[0][1]
} // 严格位置依赖的动态规划
func stoneGameII4(piles []int) int {
n := len(piles)
sum := 0
dp := make([][]int, n)
for i := range dp {
dp[i] = make([]int, n+1)
}
for i := n - 1; i >= 0; i-- {
sum += piles[i]
for m := 1; m <= n; m++ {
if i+2*m >= n {
dp[i][m] = sum
} else {
nextMin := math.MaxInt64
for x := 1; x <= 2*m; x++ {
nextMin = int(math.Min(float64(nextMin), float64(dp[i+x][int(math.Max(float64(m), float64(x)))])))
}
dp[i][m] = sum - nextMin
}
}
}
return dp[0][1]
} func main() {
piles := []int{2, 7, 9, 4, 4}
fmt.Println("stoneGameII1:", stoneGameII1(piles))
fmt.Println("stoneGameII2:", stoneGameII2(piles))
fmt.Println("stoneGameII3:", stoneGameII3(piles))
fmt.Println("stoneGameII4:", stoneGameII4(piles))
}

rust完整代码如下:

fn stone_game_ii1(piles: Vec<i32>) -> i32 {
first1(&piles, 0, 1)
} fn first1(piles: &Vec<i32>, index: usize, m: i32) -> i32 {
if index == piles.len() {
return 0;
}
let mut best = 0;
let mut pre = 0;
for i in index..piles.len().min(index + (2 * m) as usize) {
pre += piles[i];
best = best.max(pre + second1(piles, i + 1, m.max(i as i32 + 1)));
}
best
} fn second1(piles: &Vec<i32>, index: usize, m: i32) -> i32 {
if index == piles.len() {
return 0;
}
let mut worse = i32::MAX;
for i in index..piles.len().min(index + (2 * m) as usize) {
worse = worse.min(first1(piles, i + 1, m.max(i as i32 + 1)));
}
worse
} fn stone_game_ii2(piles: Vec<i32>) -> i32 {
let mut f = vec![vec![-1; piles.len() + 1]; piles.len()];
let mut s = vec![vec![-1; piles.len() + 1]; piles.len()]; first2(&piles, 0, 1, &mut f, &mut s)
} fn first2(
piles: &Vec<i32>,
index: usize,
m: usize,
f: &mut Vec<Vec<i32>>,
s: &mut Vec<Vec<i32>>,
) -> i32 {
if index == piles.len() {
return 0;
}
if f[index][m] != -1 {
return f[index][m];
}
let mut best = 0;
let mut pre = 0;
for i in index..piles.len().min(index + 2 * m) {
pre += piles[i];
best = best.max(pre + second2(piles, i + 1, m.max(i - index + 1), f, s));
}
f[index][m] = best;
best
} fn second2(
piles: &Vec<i32>,
index: usize,
m: usize,
f: &mut Vec<Vec<i32>>,
s: &mut Vec<Vec<i32>>,
) -> i32 {
if index == piles.len() {
return 0;
}
if s[index][m] != -1 {
return s[index][m];
}
let mut worse = i32::MAX;
for i in index..piles.len().min(index + 2 * m) {
worse = worse.min(first2(piles, i + 1, m.max(i - index + 1), f, s));
}
s[index][m] = worse;
worse
} fn stone_game_ii3(piles: Vec<i32>) -> i32 {
let n = piles.len();
let mut f: Vec<Vec<i32>> = vec![vec![0; n + 1]; n + 1];
let mut s: Vec<Vec<i32>> = vec![vec![0; n + 1]; n + 1]; for index in (0..n).rev() {
for m in 1..=n {
let mut pre = 0;
for (i, j) in (index..piles.len()).zip(1..=2 * m) {
pre += piles[i];
f[index][m] = f[index][m].max(pre + s[i + 1][n.min(j.max(m))]);
} s[index][m] = i32::MAX;
for (i, j) in (index..piles.len()).zip(1..=2 * m) {
s[index][m] = s[index][m].min(f[i + 1][n.min(j.max(m))]);
}
}
} f[0][1]
} fn stone_game_ii4(piles: Vec<i32>) -> i32 {
let n = piles.len();
let mut sum = 0;
let mut dp = vec![vec![0; n + 1]; n]; for i in (0..n).rev() {
sum += piles[i];
for m in 1..=n {
if i + 2 * m >= n {
dp[i][m] = sum;
} else {
let mut next_min = std::i32::MAX;
for x in 1..=2 * m {
next_min = next_min.min(dp[i + x][m.max(x)]);
}
dp[i][m] = sum - next_min;
}
}
} dp[0][1]
} fn main() {
let piles = vec![2, 7, 9, 4, 4];
let result = stone_game_ii1(piles);
println!("{}", result); let piles = vec![2, 7, 9, 4, 4];
let result = stone_game_ii2(piles);
println!("{}", result); let piles = vec![2, 7, 9, 4, 4];
let result = stone_game_ii3(piles);
println!("{}", result); let piles = vec![2, 7, 9, 4, 4];
let result = stone_game_ii4(piles);
println!("{}", result);
}

c++完整代码如下:

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits> using namespace std; int second1(vector<int>& piles, int index, int m); int first1(vector<int>& piles, int index, int m) {
if (index == piles.size()) {
return 0;
}
int best = 0;
int pre = 0;
for (int i = index, j = 1; i < piles.size() && j <= 2 * m; i++, j++) {
pre += piles[i];
best = max(best, pre + second1(piles, i + 1, max(j, m)));
}
return best;
} int second1(vector<int>& piles, int index, int m) {
if (index == piles.size()) {
return 0;
}
int worse = INT_MAX;
for (int i = index, j = 1; i < piles.size() && j <= 2 * m; i++, j++) {
worse = min(worse, first1(piles, i + 1, max(j, m)));
}
return worse;
} int stoneGameII1(vector<int>& piles) {
return first1(piles, 0, 1);
} int second2(vector<int>& piles, int index, int m, vector<vector<int>>& f, vector<vector<int>>& s); int first2(vector<int>& piles, int index, int m, vector<vector<int>>& f, vector<vector<int>>& s) {
if (index == piles.size()) {
return 0;
}
if (f[index][m] != -1) {
return f[index][m];
}
int best = 0;
int pre = 0;
for (int i = index, j = 1; i < piles.size() && j <= 2 * m; i++, j++) {
pre += piles[i];
best = max(best, pre + second2(piles, i + 1, min((int)piles.size(), max(j, m)), f, s));
}
f[index][m] = best;
return best;
} int second2(vector<int>& piles, int index, int m, vector<vector<int>>& f, vector<vector<int>>& s) {
if (index == piles.size()) {
return 0;
}
if (s[index][m] != -1) {
return s[index][m];
}
int worse = INT_MAX;
for (int i = index, j = 1; i < piles.size() && j <= 2 * m; i++, j++) {
worse = min(worse, first2(piles, i + 1, min((int)piles.size(), max(j, m)), f, s));
}
s[index][m] = worse;
return worse;
} int stoneGameII2(vector<int>& piles) {
int n = piles.size();
vector<vector<int>> f(n, vector<int>(n + 1, -1));
vector<vector<int>> s(n, vector<int>(n + 1, -1));
return first2(piles, 0, 1, f, s);
} int stoneGameII3(vector<int>& piles) {
int n = piles.size();
vector<vector<int>> f(n + 1, vector<int>(n + 1, 0));
vector<vector<int>> s(n + 1, vector<int>(n + 1, 0)); for (int index = n - 1; index >= 0; index--) {
for (int m = 1; m <= n; m++) {
int pre = 0;
for (int i = index, j = 1; i < n && j <= 2 * m; i++, j++) {
pre += piles[i];
f[index][m] = max(f[index][m], pre + s[i + 1][min(n, max(j, m))]);
}
s[index][m] = INT_MAX;
for (int i = index, j = 1; i < n && j <= 2 * m; i++, j++) {
s[index][m] = min(s[index][m], f[i + 1][min(n, max(j, m))]);
}
}
}
return f[0][1];
} int stoneGameII4(vector<int>& piles) {
int n = piles.size();
int sum = 0;
vector<vector<int>> dp(n, vector<int>(n + 1, 0));
for (int i = n - 1; i >= 0; i--) {
sum += piles[i];
for (int m = 1; m <= n; m++) {
if (i + 2 * m >= n) {
dp[i][m] = sum;
}
else {
int nextMin = INT_MAX;
for (int x = 1; x <= 2 * m; x++) {
nextMin = min(nextMin, dp[i + x][max(m, x)]);
}
dp[i][m] = sum - nextMin;
}
}
}
return dp[0][1];
} int main() {
vector<int> piles = { 2, 7, 9, 4, 4 };
cout << "stoneGameII1: " << stoneGameII1(piles) << endl;
cout << "stoneGameII2: " << stoneGameII2(piles) << endl;
cout << "stoneGameII3: " << stoneGameII3(piles) << endl;
cout << "stoneGameII4: " << stoneGameII4(piles) << endl;
return 0;
}

c完整代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h> int second1(int* piles, int pilesSize, int index, int m); int first1(int* piles, int pilesSize, int index, int m) {
if (index == pilesSize) {
return 0;
}
int best = 0;
int pre = 0;
for (int i = index, j = 1; i < pilesSize && j <= 2 * m; i++, j++) {
pre += piles[i];
best = best > (pre + second1(piles, pilesSize, i + 1, j > m ? j : m)) ? best : (pre + second1(piles, pilesSize, i + 1, j > m ? j : m));
}
return best;
} int second1(int* piles, int pilesSize, int index, int m) {
if (index == pilesSize) {
return 0;
}
int worse = INT_MAX;
for (int i = index, j = 1; i < pilesSize && j <= 2 * m; i++, j++) {
worse = worse < first1(piles, pilesSize, i + 1, j > m ? j : m) ? worse : first1(piles, pilesSize, i + 1, j > m ? j : m);
}
return worse;
} int stoneGameII1(int* piles, int pilesSize) {
return first1(piles, pilesSize, 0, 1);
} int second2(int* piles, int pilesSize, int index, int m, int** f, int** s); int first2(int* piles, int pilesSize, int index, int m, int** f, int** s) {
if (index == pilesSize) {
return 0;
}
if (f[index][m] != -1) {
return f[index][m];
}
int best = 0;
int pre = 0;
for (int i = index, j = 1; i < pilesSize && j <= 2 * m; i++, j++) {
pre += piles[i];
best = best > (pre + second2(piles, pilesSize, i + 1, j > m ? j : m, f, s)) ? best : (pre + second2(piles, pilesSize, i + 1, j > m ? j : m, f, s));
}
f[index][m] = best;
return best;
} int second2(int* piles, int pilesSize, int index, int m, int** f, int** s) {
if (index == pilesSize) {
return 0;
}
if (s[index][m] != -1) {
return s[index][m];
}
int worse = INT_MAX;
for (int i = index, j = 1; i < pilesSize && j <= 2 * m; i++, j++) {
worse = worse < first2(piles, pilesSize, i + 1, j > m ? j : m, f, s) ? worse : first2(piles, pilesSize, i + 1, j > m ? j : m, f, s);
}
s[index][m] = worse;
return worse;
} int stoneGameII2(int* piles, int pilesSize) {
int n = pilesSize;
int** f = (int**)malloc((n + 1) * sizeof(int*));
int** s = (int**)malloc((n + 1) * sizeof(int*));
for (int i = 0; i < n; i++) {
f[i] = (int*)malloc((n + 1) * sizeof(int));
s[i] = (int*)malloc((n + 1) * sizeof(int));
for (int j = 0; j <= n; j++) {
f[i][j] = -1;
s[i][j] = -1;
}
}
return first2(piles, pilesSize, 0, 1, f, s);
} int stoneGameII3(int* piles, int pilesSize) {
int n = pilesSize;
int** f = (int**)malloc((n + 1) * sizeof(int*));
int** s = (int**)malloc((n + 1) * sizeof(int*));
for (int i = 0; i <= n; i++) {
f[i] = (int*)malloc((n + 1) * sizeof(int));
s[i] = (int*)malloc((n + 1) * sizeof(int));
for (int j = 0; j <= n; j++) {
f[i][j] = 0;
s[i][j] = 0;
}
} for (int index = n - 1; index >= 0; index--) {
for (int m = 1; m <= n; m++) {
int pre = 0;
for (int i = index, j = 1; i < n && j <= 2 * m; i++, j++) {
pre += piles[i];
f[index][m] = f[index][m] > (pre + s[i + 1][j > m ? j : m]) ? f[index][m] : (pre + s[i + 1][j > m ? j : m]);
}
s[index][m] = INT_MAX;
for (int i = index, j = 1; i < n && j <= 2 * m; i++, j++) {
s[index][m] = s[index][m] < f[i + 1][j > m ? j : m] ? s[index][m] : f[i + 1][j > m ? j : m];
}
}
}
return f[0][1];
} int stoneGameII4(int* piles, int pilesSize) {
int n = pilesSize;
int sum = 0;
int** dp = (int**)malloc(n * sizeof(int*));
for (int i = 0; i < n; i++) {
dp[i] = (int*)malloc((n + 1) * sizeof(int));
for (int j = 0; j <= n; j++) {
dp[i][j] = 0;
}
}
for (int i = n - 1; i >= 0; i--) {
sum += piles[i];
for (int m = 1; m <= n; m++) {
if (i + 2 * m >= n) {
dp[i][m] = sum;
}
else {
int nextMin = INT_MAX;
for (int x = 1; x <= 2 * m; x++) {
nextMin = nextMin < dp[i + x][m > x ? m : x] ? nextMin : dp[i + x][m > x ? m : x];
}
dp[i][m] = sum - nextMin;
}
}
}
return dp[0][1];
} int main() {
int piles[] = { 2, 7, 9, 4, 4 };
int pilesSize = sizeof(piles) / sizeof(piles[0]);
printf("stoneGameII1: %d\n", stoneGameII1(piles, pilesSize));
printf("stoneGameII2: %d\n", stoneGameII2(piles, pilesSize));
printf("stoneGameII3: %d\n", stoneGameII3(piles, pilesSize));
printf("stoneGameII4: %d\n", stoneGameII4(piles, pilesSize));
return 0;
}

2023-07-05:爱丽丝和鲍勃继续他们的石子游戏 许多堆石子 排成一行,每堆都有正整数颗石子 piles[i] 游戏以谁手中的石子最多来决出胜负。 爱丽丝和鲍勃轮流进行,爱丽丝先开始。最初,的更多相关文章

  1. 2019.07.05 纪中_B

    今日膜拜:czj大佬orz%%% 2019.07.05[NOIP提高组]模拟 B 组 今天做题的时候大概能判断出题人的考点,可是就是没学过...特别痛苦 T0:栈的定义,模拟就好了T1:感觉像是找规律 ...

  2. Murano Weekly Meeting 2016.07.05

    Meeting time: 2016.July.05 1:00~2:00 Chairperson:  Kirill Zaitsev, from Mirantis Meeting summary: 1. ...

  3. <2013 07 05> 804.15. 4--> TI MSP430+CC2520 调试

    这一周,实际参与eCar项目的工作正式展开. 来TUM的第一个月,主要熟悉了eCar的机电结构,特别是熟悉了eCar的IT(Information Technology),包括硬件和代码. 来的时候, ...

  4. 2016/07/05 zend optimizer

    Zend Optimizer是由PHP核心引擎“Zend” http://www.zend.com 创建者Zend技术公司所开的免费PHP优化软件.据Zend公司透露使用这个软件某些情况下至少可以提高 ...

  5. 1140. 石子游戏 II (Medium)

    问题描述 1140. 石子游戏 II (Medium) 爱丽丝和鲍勃继续他们的石子游戏.许多堆石子 排成一行,每堆都有正整数颗石子 piles[i].游戏以谁手中的石子最多来决出胜负. 爱丽丝和鲍勃轮 ...

  6. [Swift]LeetCode877. 石子游戏 | Stone Game

    Alex and Lee play a game with piles of stones.  There are an even number of piles arranged in a row, ...

  7. Bit Operation妙解算法题

    5道巧妙位操作的算法题. ***第一道*** 题目描述 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次.找出那个只出现了一次的元素. 说明: 你的算法应该具有线性时间复杂度. ...

  8. leetcode 877. 石子游戏

    题目描述: 亚历克斯和李用几堆石子在做游戏.偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] . 游戏以谁手中的石子最多来决出胜负.石子的总数是奇数,所以没有平局. 亚历克斯和李轮流进行,亚 ...

  9. Leetcode之动态规划(DP)专题-877. 石子游戏(Stone Game)

    Leetcode之动态规划(DP)专题-877. 石子游戏(Stone Game) 亚历克斯和李用几堆石子在做游戏.偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] . 游戏以谁手中的石子最 ...

  10. leetcode 877. Stone Game 详解 -——动态规划

    原博客地址 https://blog.csdn.net/androidchanhao/article/details/81271077 题目链接 https://leetcode.com/proble ...

随机推荐

  1. abc285G

    ABC 285 G - Tatami Solution 网络流 网格图是一个天然二分图, 可以按 横纵坐标之和 的奇偶性将相邻两格分属于左部和右部. 记'?' 或 '2' 的格子为待匹配点, 记横纵坐 ...

  2. pandas技巧

    1. 计算月初.2022-05-03 得到2022-05-01 df['month']=df['purchase_date'].apply(lambda x : x.replace(day=1))

  3. 企业应用可观测性利器!华为云CodeArts APM发布

    摘要:近日,华为云全链路应用性能管理服务CodeArts APM全新上线,提供端到端的全链路性能管理服务,涵盖前端监控.应用性能监控,全面拥抱开源生态. 本文分享自华为云社区<企业应用可观测性利 ...

  4. .NET实现解析字符串表达式

    一.引子·功能需求 我们创建了一个 School 对象,其中包含了教师列表和学生列表.现在,我们需要计算教师平均年龄和学生平均年龄. //创建对象 School school = new School ...

  5. rails的接口查询详解

    Retrieving Objects from the Database find "find"是一种常用的数据库查询方法,在Rails中被用于从数据库中查找单个记录.它可以接收一 ...

  6. Python-趣味小程序

    1.效果 2.代码 import sys import time def print_act(word): #print('\n'+' '+'\r') #让光标回到行首 sys.stdout.writ ...

  7. 2022-09-30:以下go语言代码输出什么?A: true true false true false; B: true false false true false; C: true true

    2022-09-30:以下go语言代码输出什么?A: true true false true false: B: true false false true false: C: true true ...

  8. 2022-02-02:最接近的二叉搜索树值 II。 给定一个不为空的二叉搜索树和一个目标值 target,请在该二叉搜索树中找到最接近目标值 target 的 k 个值。 注意: 给定的目标值 ta

    2022-02-02:最接近的二叉搜索树值 II. 给定一个不为空的二叉搜索树和一个目标值 target,请在该二叉搜索树中找到最接近目标值 target 的 k 个值. 注意: 给定的目标值 tar ...

  9. GRPC与 ProtoBuf 的理解与总结

    转载请注明出处: 1.GRPC 官网:https://www.grpc.io/ gRPC 官方文档中文版:http://doc.oschina.net/grpc RPC 框架的目标就是让远程服务调用更 ...

  10. xshell入门及Linux常用命令

    一.首先您的xshell先连接上需要远程连接的服务器. 二.打开连接,出现下记页面,就证明与服务器连接正常了. 三.接下来,我们就可以使用命令做一系列操作了. 3-1:cd 是进入下一级目录命令 例如 ...