题目描述:

亚历克斯和李用几堆石子在做游戏。偶数堆石子排成一行,每堆都有正整数颗石子 piles[i] 。

游戏以谁手中的石子最多来决出胜负。石子的总数是奇数,所以没有平局。

亚历克斯和李轮流进行,亚历克斯先开始。 每回合,玩家从行的开始或结束处取走整堆石头。 这种情况一直持续到没有更多的石子堆为止,此时手中石子最多的玩家获胜。

假设亚历克斯和李都发挥出最佳水平,当亚历克斯赢得比赛时返回 true ,当李赢得比赛时返回 false 。

示例:

输入:[5,3,4,5]
输出:true
解释:
亚历克斯先开始,只能拿前 5 颗或后 5 颗石子 。
假设他取了前 5 颗,这一行就变成了 [3,4,5] 。
如果李拿走前 3 颗,那么剩下的是 [4,5],亚历克斯拿走后 5 颗赢得 10 分。
如果李拿走后 5 颗,那么剩下的是 [3,4],亚历克斯拿走后 4 颗赢得 9 分。
这表明,取前 5 颗石子对亚历克斯来说是一个胜利的举动,所以我们返回 true 。

思路分析:

是一个博弈问题。由于双方都是足够聪明的人,所以直接用贪心是不行的。

需要用到动态规划求解。dp[i][j][0]表示,在有第i堆到第j堆石子的情况下,先手的最大石子数。dp[i][j][1]则表示后手。状态转移方程是,dp[i][j][0] = max(piles[i]+dp[i+1][j][1], piles[j]+dp[i][j-1][1]),当先手选择最左边的,dp[i][j][1] = dp[i+1][j][0]; 当先手选择最右边的,dp[i][j][1] = dp[i][j-1][0]。这里的先手和后手是相对的,因此在更新是交替应用。

代码:

class Solution {
public:
bool stoneGame(vector<int>& piles) {
int n = piles.size();
int dp[n][n][2] = {0};
for(int i=0; i<n; i++)
{
dp[i][i][0] = piles[i];
dp[i][i][1] = 0;
}
for(int l=1; l<n; l++)
{
for(int i=0; i+l<n; i++)
{
int j = l+i;
int left = piles[i] + dp[i+1][j][1];
int right = piles[j] + dp[i][j-1][1];
if(left > right)
{
dp[i][j][0] = left;
dp[i][j][1] = dp[i+1][j][0];
}
else
{
dp[i][j][0] = right;
dp[i][j][1] = dp[i][j-1][0];
}
}
}
return dp[0][n-1][0]-dp[0][n-1][1]>0;
}
};

leetcode 877. 石子游戏的更多相关文章

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

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

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

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

  3. BZOJ 1115: [POI2009]石子游戏Kam

    1115: [POI2009]石子游戏Kam Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 883  Solved: 545[Submit][Stat ...

  4. Games:取石子游戏(POJ 1067)

    取石子游戏 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 37662   Accepted: 12594 Descripti ...

  5. {CSDN}{英雄会}{砍树、石子游戏}

    砍树 思路: 可以将题目意图转化为:给定一棵树,求其中最接近总权值一半的子树. DFS求每个节点的所有子节点的权值和,遍历每个节点,最接近总权值一半的即为答案.复杂度O(N). 石子游戏: 思路: 一 ...

  6. HDU 2176 取(m堆)石子游戏(Nim)

    取(m堆)石子游戏 题意: Problem Description m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.例如5堆 5,7,8,9,1 ...

  7. HDU 2516 取石子游戏(斐波那契博弈)

    取石子游戏 Time Limit: 2000/1000 MS(Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi ...

  8. hdu 1527 取石子游戏(Wythoff Game)

    题意:Wythoff Game 思路:Wythoff Game #include<iostream> #include<stdio.h> #include<math.h& ...

  9. HDU 2516 取石子游戏(FIB博弈)

    取石子游戏 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

随机推荐

  1. 【优化】COUNT(1)、COUNT(*)、COUNT(常量)、COUNT(主键)、COUNT(ROWID)、COUNT(非空列)、COUNT(允许为空列)、COUNT(DISTINCT 列名)

    [优化]COUNT(1).COUNT(*).COUNT(常量).COUNT(主键).COUNT(ROWID).COUNT(非空列).COUNT(允许为空列).COUNT(DISTINCT 列名) 1. ...

  2. .Net core 如何生成Nuget包

    以前引用了很多neget包,觉得nuget包方便了很多,是不是有些通用的代码可以封装到nuget中,想要用的时候引用就可以了, 这样其实有两个好处: 1. 首先不用重复的coding,节约了时间. 2 ...

  3. 常用内置模块(二)--logging、hashlib、shelve、xml、configparser

    一.logging模块 1.logging作用 1. 控制日志级别  2. 控制日志格式  3. 控制输出的目标为文件 2.日志级别 1 logging.debug( 2 logging.info( ...

  4. JMETER 使用BeanShell 配合 if 控制器实现逻辑控制

    业务场景 在登录后,我们根据登录的响应,判断是否执行下一步的操作. 实现步骤 1.在登录采样器树中增加BeanShell 监听器. 作用是在线程上下文变量中增加一个变量,表示登录是否成功. beans ...

  5. 《linux就该这么学》课堂笔记11 LVM、防火墙初识

    1.常用的LVM部署命令 功能/命令 物理卷管理 卷组管理 逻辑卷管理 扫描 pvscan vgscan lvscan 建立 pvcreate vgcreate lvcreate 显示 pvdispl ...

  6. (十)Kubernetes ConfigMap和Secret

    ConfigMap资源 介绍 ConfigMap是让配置文件从镜像中解耦,让镜像的可移植性和可复制性.许多应用程序会从配置文件.命令行参数或环境变量中读取配置信息.这些配置信息需要与docker im ...

  7. package的xml格式的改变

    package.xml文件格式由1到2发生了一些变化: 格式2有如下一行: <package format="2"> 依赖也发生一些变化<depend> 格 ...

  8. python老师博客

    前端基础之HTML http://www.cnblogs.com/yuanchenqi/articles/6835654.html 前端基础之CSS http://www.cnblogs.com/yu ...

  9. python 应用开发之-用base64 对图片文件的编码和解码处理

    用base64 对图片文件的编码和解码处理 import base64 def convert(image): f = open(image) img_raw_data = f.read() f.cl ...

  10. python应用-已知三角形的边长求他的面积和周长

    """ 已知三角形的边长求他的面积和周长 Author:罗万财 Date:2017-3-3 """ import math a=float( ...