1140. 石子游戏 II (Medium)
问题描述
爱丽丝和鲍勃继续他们的石子游戏。许多堆石子 排成一行,每堆都有正整数颗石子
piles[i]
。游戏以谁手中的石子最多来决出胜负。
爱丽丝和鲍勃轮流进行,爱丽丝先开始。最初, M = 1
。
在每个玩家的回合中,该玩家可以拿走剩下的 前 X
堆的所有石子,其中 1 <= X <= 2M
。然后,令
M = max(M, X)
。
游戏一直持续到所有石子都被拿走。
假设爱丽丝和鲍勃都发挥出最佳水平,返回爱丽丝可以得到的最大数量的石头。
示例 1:
输入:piles = [2,7,9,4,4]
输出:10
解释:如果一开始Alice取了一堆,Bob取了两堆,然后Alice再取两堆。爱丽丝可以得到2 + 4 + 4 =
10堆。如果Alice一开始拿走了两堆,那么Bob可以拿走剩下的三堆。在这种情况下,Alice得到2 + 7 =
9堆。返回10,因为它更大。
示例 2:
输入:piles = [1,2,3,4,5,100]
输出:104
提示:
1 <= piles.length <= 100
1 <= piles[i] <= 10⁴
解题思路
首先这里要明确发挥最佳水平的含义:
如果自己拿了前x
块石子之后,对方所能拿到的石子最少,这就是博弈中的发挥最佳水平,对应到dfs
,明白了这一点就能写出递归和记忆化搜索,注意这里还需要用到后缀数组。
写出记忆化搜索之后可以改写成动态规划。
代码
记忆化搜索
class Solution {
public:
int dfs(int idx_start, int M, vector<int> &postfix, int n, vector<vector<int>> &cach) {
if (idx_start >= n)
return 0;
int minnum = 100001;
if (cach[idx_start][M] >= 0) {
return cach[idx_start][M];
}
for (int i = idx_start + 1; i <= idx_start + 2 * M && i <= n; i++) { // i表示下一个人拿石子的开始位置,所以i至少为idx_start+1
int tmp = dfs(i, std::max(i - idx_start, M), postfix, n, cach);
if (minnum > tmp) {
minnum = tmp;
}
}
cach[idx_start][M] = postfix[idx_start] - minnum;
return cach[idx_start][M];
}
int stoneGameII(vector<int>& piles) {
int n = piles.size();
vector<int> postfix(n + 1, 0);
for (int i = n - 1; i >= 0; i--) {
postfix[i] = postfix[i + 1] + piles[i];
}
vector<vector<int>> cach(n + 1, vector<int>(n, -1));
return dfs(0, 1, postfix, n, cach);
}
};
动态规划
class Solution {
public:
int stoneGameII(vector<int> &piles) {
int n = piles.size();
vector<int> postfix(n + 1, 0);
// 后缀和数组
for (int i = n - 1; i >= 0; i--) {
postfix[i] = postfix[i + 1] + piles[i];
}
// dp[i][j]表示从坐标`i`开始拿`j`个所能获得的最大石子数
vector<vector<int>> dp(n + 1, vector<int>(n + 1, 0));
for (int i = n - 1; i >= 0; i--) {
for (int M = 1; M <= i / 2 + 1; M++) {
if (i + 2 * M >= n) { // 说明可以直接拿走剩余的石子
dp[i][M] = postfix[i];
} else {
int min_num = INT_MAX;
for (int x = 1; x <= 2 * M; x++) {
// 因为从dp[i + x]递推到dp[i],所以`i`要倒序循环
min_num = std::min(min_num, dp[i + x][std::max(M, x)]);
}
dp[i][M] = postfix[i] - min_num;
}
}
}
return dp[0][1];
}
};
1140. 石子游戏 II (Medium)的更多相关文章
- BZOJ 1115: [POI2009]石子游戏Kam
1115: [POI2009]石子游戏Kam Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 883 Solved: 545[Submit][Stat ...
- XDU 1161 - 科协的数字游戏II
Problem 1161 - 科协的数字游戏II Time Limit: 1000MS Memory Limit: 65536KB Difficulty: Total Submit: 112 ...
- Games:取石子游戏(POJ 1067)
取石子游戏 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 37662 Accepted: 12594 Descripti ...
- {CSDN}{英雄会}{砍树、石子游戏}
砍树 思路: 可以将题目意图转化为:给定一棵树,求其中最接近总权值一半的子树. DFS求每个节点的所有子节点的权值和,遍历每个节点,最接近总权值一半的即为答案.复杂度O(N). 石子游戏: 思路: 一 ...
- HDU 2176 取(m堆)石子游戏(Nim)
取(m堆)石子游戏 题意: Problem Description m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.例如5堆 5,7,8,9,1 ...
- HDU 2516 取石子游戏(斐波那契博弈)
取石子游戏 Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...
- lintcode: 跳跃游戏 II
跳跃游戏 II 给出一个非负整数数组,你最初定位在数组的第一个位置. 数组中的每个元素代表你在那个位置可以跳跃的最大长度. 你的目标是使用最少的跳跃次数到达数组的最后一个位置. 样例 给出数组A = ...
- hdu 1527 取石子游戏(Wythoff Game)
题意:Wythoff Game 思路:Wythoff Game #include<iostream> #include<stdio.h> #include<math.h& ...
- HDU 2516 取石子游戏(FIB博弈)
取石子游戏 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- hdu 2176 取(m)石子游戏
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2176 题意分析:给出M堆石子,两人交替取子,给出先手能否胜利. 不能输出No, 能则输出Yes并给出第 ...
随机推荐
- Delete `␍` prettier/prettier Vue 可悬浮按钮
Delete `␍` prettier/prettier 代码格式化不一致,换行符冲突.UNIX/Linux 使用的是 0x0A(LF), DOS/Windows 一直使用 0x0D0A(CRLF) ...
- Excel之VLOOKUP()函数的基本用法
语法: VLOOKUP(lookup_value,table_array,col_index_num,[range_lookup]) 规则: 注意: 查找的值:内容需要完全一样 查找范围:查找范围的 ...
- RabbitMQ Linux安装与启动服务
本文转载自 https://blog.csdn.net/chengmin123456789/article/details/124710277 1.先下载 erlang-23.2.3-1.el7.x8 ...
- APP稳定性测试Monkey工具介绍
一.Monkey工具简介 1.monkey的来源: Monkey是一个命令行工具,使用安卓调试桥(adb)来运行它,模拟用户:触摸屏幕.滑动Trackball.按键等随机事件流来对设备上的程序进行压力 ...
- 均值、中值、高斯、non-local means算法详解
文章仅为个人理解,如有不妥之处欢迎指正. 写几个常见的图像去噪滤波器. 1.均值滤波器 均值滤波器是最简单的图像平滑滤波器,其3*3的模板为 1 9 [ 1 1 1 1 1 1 1 1 1 ] \fr ...
- [人脸识别]06-JPG人脸检测
1-程序 #导入CV模块 import cv2 as cv def face_detect_fun(): gray=cv.cvtColor(img,cv.COLOR_BGR2GRAY) print(c ...
- vs 工具 dumpbin & corflags
dumpbin 查看 dll 接口函数 > dumpbin /exports "/path/to/dll" dumpbin 查看 exe.dll 依赖的动态库 > du ...
- OS-lab2
OS-lab2 启动之后,我们的操作系统要能运行,需要一个载体,就是内存.内存的访问不是直接的,而是通过MMU完成.在完成MMU之前,我们先看看一些需要用到的宏定义和函数. include pmap. ...
- java对excel的操作
1.对比任意两张excel表是否有不同行 并输出哪一行那一列不同 2.包含解析合并单元格方法 3.比较主要思路 a.解析excel: b.遍历第一张表数据所有行 c.遍历第二张表数据所有行 d.遍历第 ...
- KingbaseES V8R6备份恢复案例之---自定义表空间指定恢复目录数据恢复
案例说明: KingbaseES V8R6在通过sys_rman执行物理备份恢复时,可以通过参数'--kb1-path',指定恢复的数据(data)目录,但如果原备份中包含自定义表空间时,需要建立表空 ...