Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from either end of the array followed by the player 2 and then player 1 and so on. Each time a player picks a number, that number will not be available for the next player. This continues until all the scores have been chosen. The player with the maximum score wins.

Given an array of scores, predict whether player 1 is the winner. You can assume each player plays to maximize his score.

Example 1:

Input: [1, 5, 2]
Output: False
Explanation: Initially, player 1 can choose between 1 and 2.
If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2).
So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
Hence, player 1 will never be the winner and you need to return False.

Example 2:

Input: [1, 5, 233, 7]
Output: True
Explanation: Player 1 first chooses 1. Then player 2 have to choose between 5 and 7. No matter which number player 2 choose, player 1 can choose 233.
Finally, player 1 has more score (234) than player 2 (12), so you need to return True representing player1 can win.

Note:

  1. 1 <= length of the array <= 20.
  2. Any scores in the given array are non-negative integers and will not exceed 10,000,000.
  3. If the scores of both players are equal, then player 1 is still the winner.

思路:

参考自

http://www.voidcn.com/blog/starstar1992/article/p-6497962.html

https://discuss.leetcode.com/topic/76472/clean-3ms-c-dp-solution-with-detailed-explanation

https://discuss.leetcode.com/topic/76327/c-dp-solution-with-explanation

bool PredictTheWinner(vector<int>& nums)
{
int n = nums.size();
vector<vector<int>>dp(n, vector<int>(n));
vector<int>sum(n);
sum[] = nums[];
dp[][] = nums[];
for (int i = ; i < n;i++)
{
sum[i] += sum[i - ] + nums[i];
dp[i][i] = nums[i];
}
for (int i = ; i < n;i++)
{
for (int j = ; i + j < n;j++)
{
dp[j][i + j] = max(sum[i+j]-sum[j]+nums[j] -dp[j+][i+j],sum[i+j]-sum[j]+nums[j]-dp[j][i+j-]);
}
}
return * dp[][n - ] >= sum[n - ];
}

如上图所示,dp为二维数组,最终要求得是dp[0][n-1]那么,需要不断的去迭代更新dp[i][j]的值。求得过程类似上图,从对角线的上方

从左上到右下求dp[i][j]的值。也就是说求dp[i][j]需要用到它左边和下边的值 即左边dp[i][j-1]和下边dp[i+1][j]的值。

这一题用动态规划来解决。 
对于原数组A[0,….,n-1],我们定义 
dp[i][j]表示原数组中从i到j的这么多数中,按照游戏规则,某个玩家所能获得的最大分数。 
假设这个分数此时属于palyer1,那么dp[i+1][j]或者dp[i][j-1]表示player2玩家所能获得的最大分数。因为对于player1来讲,他第一次选择要么是第i个数,要么是第j个数,所以对于player2来讲,就分两种情况取最大。

另外我们设从i到j的所有数的和是sum[i,j],则可以得到递推公式:(动态规划最明显的标识) 
dp[i][j]=max(sum[i+1][j]-dp[i+1][j]+nums[i], sum[i][j-1]-dp[i][j-1]+nums[j]) 。

这个需要好好想想!其实不难! 
化简一下: 
dp[i][j]=max(sum[i][j]-dp[i+1][j], sum[i][j]-dp[i][j-1]) 。

但是写代码实现时,我们要注意: 
首先要得到dp[i][i]的值,之后依次得到: 
dp[0][1],dp[1,2],dp[2,3]…dp[n-2][n-1] 
之后再得到dp[0][2],dp[1][3],…

for(int i=1;i<n;i++)
for(int j=0;i+j<n;j++)
dp[j][i+j]=max(sum[i+j]-sum[j]+nums[j]-dp[j+1][i+j],sum[i+j]-sum[j]+nums[j]-dp[j][i+j-1]);

所以这段代码的实现意图就比较明显了! 
另外,注意sum[i+j]-sum[j]+nums[j]而不用sum[i+j]-sum[j-1]来求解从i到j的和,是为了考虑j=0时的情况。

细节处比较多,很考察能力!

leetcode-486-Predict the Winner的更多相关文章

  1. LN : leetcode 486 Predict the Winner

    lc 486 Predict the Winner 486 Predict the Winner Given an array of scores that are non-negative inte ...

  2. [LeetCode] 486. Predict the Winner 预测赢家

    Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...

  3. 随手练——博弈论入门 leetcode - 486. Predict the Winner

    题目链接:https://leetcode.com/problems/predict-the-winner/ 1.暴力递归 当前数组左边界:i,右边界:j: 对于先发者来说,他能取到的最大值是:max ...

  4. [leetcode] 486. Predict the Winner (medium)

    原题 思路: 解法一: 转换比较拿取分数多少的思路,改为考虑 player拿的分数为正,把Player2拿的视为负,加上所有分数,如果最后结果大于0则Player1赢. 思考得出递归表达式: max( ...

  5. 【LeetCode】486. Predict the Winner 解题报告(Python)

    [LeetCode]486. Predict the Winner 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: ht ...

  6. LC 486. Predict the Winner

    Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...

  7. 【leetcode】486. Predict the Winner

    题目如下: Given an array of scores that are non-negative integers. Player 1 picks one of the numbers fro ...

  8. 486. Predict the Winner

    Given an array of scores that are non-negative integers. Player 1 picks one of the numbers from eith ...

  9. 486 Predict the Winner 预测赢家

    给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端拿取分数,然后玩家1拿,…….每次一个玩家只能拿取一个分数,分数被拿取之后不再可取.直到没有剩余分数 ...

  10. Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner)

    Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner) 给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端 ...

随机推荐

  1. Java学习笔记——序列化和反序列化

    寒雨连江夜入吴,平明送客楚山孤. 洛阳亲友如相问,一片冰心在玉壶. --芙蓉楼送辛渐 持久化数据的第一种方式.在序列化之前也可以把数据打散逐行存储在文件中,然后在逐行读取. 比如定Student类 用 ...

  2. @PathVariable和@RequestParam的区别,@SessionAttributes

    简介: handler method参数绑定常用的注解,我们根据他们处理的Request的不同内容部分分为四类: A:处理requet uri部分(这里指uri template中variable,不 ...

  3. Java_中快速获取系统时间

    直接调用System的currentTimeMillis()即可! long start = System.currentTimeMillis(); System.out.println(" ...

  4. MySQL · 引擎特性 · InnoDB Buffer Pool

    前言 用户对数据库的最基本要求就是能高效的读取和存储数据,但是读写数据都涉及到与低速的设备交互,为了弥补两者之间的速度差异,所有数据库都有缓存池,用来管理相应的数据页,提高数据库的效率,当然也因为引入 ...

  5. OBS实现直播解决方案【html实现直播】

    项目的需要,要整一个视频直播,但又不想在其他平台那种直播室盗链展示,那我就直接用播放器来实现rtmp流媒体服务器推流吧!没废话,走起 1.你要有一个媒体服务器,暂时用[盘古云],这个还好,算是不错的平 ...

  6. Java 8 Learn Notes - Streams

    Main reference [1] http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples 1. How Stream ...

  7. on方法使用注意事项

    on(eventType,[childSelector],[data],fn) 采用事件委托机制绑定事件,好处是子元素动态加入时无需再次绑定. on方法可以传入childSelector指定添加事件处 ...

  8. javaWeb学习总结(7)-会话之session技术

    什么是Session 使用Cookie和附加URL参数都可以将上一次请求的状态信息传递到下一次请求中,但是如果传递的状态信息较多,将极大降低网络传输效率和增大服务器端程序处理的难度. Session技 ...

  9. JQuery模拟实现天猫购物车动画效果

    测试程序源代码下载地址:源码 一.功能描述: 1.点击购买按钮,模拟抛物线将物品弹到购物车里: 2.购物车添加物品后,显示+1动画: 效果图如下: 实现如下: 1.导入jquery相关的包: < ...

  10. Pandas日期数据处理:如何按日期筛选、显示及统计数据

    前言 pandas有着强大的日期数据处理功能,本期我们来了解下pandas处理日期数据的一些基本功能,主要包括以下三个方面: 按日期筛选数据 按日期显示数据 按日期统计数据 运行环境为 windows ...