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. post-css/less/sass样式嵌套与命令之"&"符号—BEM

    看了< less 的 & 详解 https://www.jianshu.com/p/127b0974cfc3>,对于此文再做一别补充 常见用法: 直接嵌套写法 .a{   colo ...

  2. IIS部署网站,运行网站时出现的错误

    大概情况就是一台新电脑在部署IIS中出现的各种问题,做了一个整合,大部分都是找的别人写的博客,但是有的原文连接找不到了,见谅!   问题:   不能在此路径中使用此配置节.如果在父级别上锁定了该节,便 ...

  3. mysql迁移:mysqldump导出数据库

    问题描述:要将一个mysql中六个数据库导出来,使用mysqldump导出 mysqldump使用语法:mysqldump -uroot -p -S /data/mysql/db_itax_m/mys ...

  4. Docker Compose 部署GitLab

    先决条件 Docker Engine和Docker Compose是必需的.请参阅在CentOS上安装Docker Engine. 建议使用4核的服务器,同时至少分配4G的内存,理论上4核4G可最多支 ...

  5. springboot-poi ---封装注解式导入导出

    此demo 是基于poi封装对象式注解导入导出,项目框架为springboot项目! 简单的说明一下此demo涉及到的知识点,希望能给初学者带来方便! poi-excel 基本操作(工具) 自定义注解 ...

  6. JAVA注解@Scheduled 不执行

    spring boot项目需要在启动类加上注解 @EnableScheduling 定义一个接口 StockTask.java 1 public interface StockTask { 2 pub ...

  7. [OpenCV-Python] 6 OpenCV 中的绘图函数

    文章目录 OpenCV-Python: II OpenCV 中的 Gui 特性 6 OpenCV 中的绘图函数 6.1 画线 6.2 画矩形 6.3 画圆 6.4 画椭圆 6.5 画多边形 6.6 在 ...

  8. 音视频八股文(8)-- h264 AnnexB三层结构

    NALU(Network Abstract Layer Unit) ⾳视频编码在流媒体和⽹络领域占有重要地位:流媒体编解码流程⼤致如下图所示: H264简介 H.264从1999年开始,到2003年形 ...

  9. 2021-10-22:颠倒二进制位。颠倒给定的 32 位无符号整数的二进制位。提示:请注意,在某些语言(如 Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不

    2021-10-22:颠倒二进制位.颠倒给定的 32 位无符号整数的二进制位.提示:请注意,在某些语言(如 Java)中,没有无符号整数类型.在这种情况下,输入和输出都将被指定为有符号整数类型,并且不 ...

  10. 【GiraKoo】Github无法打开,导致无法下载Git安装包

    环境 Windows 11 原因 Git应用的安装程序在Github上,由于Github访问不稳定,导致无法下载. 对策 打开迅雷.将下载链接拷贝进去,利用迅雷的P2P技术,从其他网友处进行下载. 打 ...