每日一题-——LeetCode(486) 预测赢家
题目描述:
给定一个表示分数的非负整数数组。 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端拿取分数,然后玩家1拿,……。每次一个玩家只能拿取一个分数,分数被拿取之后不再可取。直到没有剩余分数可取时游戏结束。最终获得分数总和最多的玩家获胜。
给定一个表示分数的数组,预测玩家1是否会成为赢家。你可以假设每个玩家的玩法都会使他的分数最大化。
示例1:
输入: [1, 5, 2] 输出: False 解释: 一开始,玩家1可以从1和2中进行选择。 如果他选择2(或者1),那么玩家2可以从1(或者2)和5中进行选择。如果玩家2选择了5,那么玩家1则只剩下1(或者2)可选。 所以,玩家1的最终分数为 1 + 2 = 3,而玩家2为 5。 因此,玩家1永远不会成为赢家,返回 False。
示例2:
输入: [1, 5, 233, 7] 输出: True 解释: 玩家1一开始选择1。然后玩家2必须从5和7中进行选择。无论玩家2选择了哪个,玩家1都可以选择233。 最终,玩家1(234分)比玩家2(12分)获得更多的分数,所以返回 True,表示玩家1可以成为赢家。
注意:
- 1 <= 给定的数组长度 <= 20.
- 数组里所有分数都为非负数且不会大于10000000。
- 如果最终两个玩家的分数相等,那么玩家1仍为赢家。
解析:
对于偶数个数字的数组,玩家1一定获胜。因为一定能找到一个最优的方法使自己赢,如果输了那就不是最优的方法,那就按玩家2的方法拿,如果还输,那就再把玩家2的方法拿来用,每个玩家都足够聪明,所以玩家1一定能找到一个最优的拿法使自己赢
对于奇数个数字的数组,利用动态规划(dynamic programming)计算。 首先证明最优子结构性质。对于数组[0..n-1]中的子数组[i..j],假设玩家1在子数组[i..j]中的拿法是最优的,即拿的分数比玩家2多出最多。假设玩家1拿了i,则[i+1..j]中玩家1拿的方法也一定是最优的。利用反证法证明:如果玩家1在[i+1..j]中有更优的拿法,即玩家1在[i+1...j]可以拿到更多的分数,则玩家在[i..j]中拿到的分数就会比假设的最优拿法拿到的分数更多,显然矛盾。如果玩家1拿了j,同理可证矛盾。 所以当前问题的最优解包含的子问题的解一定也是子问题的最优解。
定义dp[i][j]为在数组[i,j]中先手比后手多拿的最大分数。这里开始时先手是玩家1,若他先拿左边的nums[i]分数,在余下数组[i+1,j]中,玩家2就为先手了,玩家2与玩家1一样聪明,所以在剩余的[i+1,j]数组中,
玩家2比玩家1要多dp[i+1][j]分,同理,玩家1先拿右边的nums[j]分数,那玩家2要比玩家1在数组[i,j-1]中多拿dp[i][j-1]分,玩家1只有这两种从两端拿的情况,所以玩家1(先手)在数组[i.j]中要比玩家2多拿(nums[i]-dp[i+1][j])或者
(nums[j]-dp[i][j-1])分,再看dp[i][j]的定义,则得出这个公式:dp[i][j]=max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1])
我们在看i,j的取值,我们所要求的结果是dp[0][n-1],为了方便n个数从左到右位置是0,1,2,...n-1。只要dp[0][n-1]大于等于零,就表示玩家1比玩家2的多拿的分数多。要求dp[0][n-1],就要知道dp[1][n-1]与dp[0][n-2]的取值。一种遍历方法是先取最后两个的值,再逐个往前增加元素,例如4个数[0,1,2,3],先求dp[2][3],再求dp[1][2],dp[1][3],之后dp[1][3]=max(1-dp[2][3],3-dp[1][2]).在之后就接着求dp[0][1],dp[0][2],dp[0][3],结果dp[0][3]=max(0-dp[1][3],3-dp[0][2]),等式右边都是已知数。
代码:
class Solution:
def PredictTheWinner2(self, nums):
n = len(nums)
if n % 2 == 0 or n == 1:
return True
dp = [[0] * n for _ in range(n)]
for i in reversed(range(n)):
for j in range(i+1, n):
#print(i,j)
dp[i][j] = max(nums[i] - dp[i+1][j], nums[j] - dp[i][j-1])
return dp[0][-1] >= 0
大佬链接:https://leetcode-cn.com/problems/predict-the-winner/solution/python-dong-tai-gui-hua-by-zhuhh/
https://leetcode-cn.com/problems/predict-the-winner/comments/78786
每日一题-——LeetCode(486) 预测赢家的更多相关文章
- 每日一题 LeetCode 486. 预测赢家 【递推】【前缀和】【动态规划】
题目链接 https://leetcode-cn.com/problems/predict-the-winner/ 题目说明 题解 主要方法:递推:动态规划:前缀和 解释说明: 求前缀和 pre_nu ...
- Java实现 LeetCode 486 预测赢家
486. 预测赢家 给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端拿取分数,然后玩家1拿,--.每次一个玩家只能拿取一个分数,分数被拿取之后不再可 ...
- leetcode 486 预测赢家
题目描述 给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端拿取分数,然后玩家1拿,--.每次一个玩家只能拿取一个分数,分数被拿取之后不再可取.直到没 ...
- Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner)
Leetcode之动态规划(DP)专题-486. 预测赢家(Predict the Winner) 给定一个表示分数的非负整数数组. 玩家1从数组任意一端拿取一个分数,随后玩家2继续从剩余数组任意一端 ...
- 每日一题-——LeetCode(121)买卖股票的最佳时机
题目描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格.如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润.注意你不能在买入股票前卖出股票 ...
- 每日一题-——LeetCode(78)子集
给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集).输入: nums = [1,2,3]输出:[ [3], [1], [2], [1,2,3], [1,3], [2, ...
- 每日一题-——LeetCode(46)全排列
题目描述: 给定一个没有重复数字的序列,返回其所有可能的全排列.输入: [1,2,3]输出:[ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ...
- 每日一题 LeetCode 679. 24点游戏 【递归】【全排列】
题目链接 https://leetcode-cn.com/problems/24-game/ 题目说明 题解 主要方法:递归 + 全排列 解释说明: 将 4 个数进行组合形成算式,发现除了 (a❈b) ...
- 每日一题LeetCode 8. 字符串转换整数 (atoi)
问题描述 请你来实现一个 atoi 函数,使其能将字符串转换成整数. 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止. 当我们寻找到的第一个非空字符为正或者负号时,则将 ...
随机推荐
- 抓取二维数组某值出来,到一维数组---array_column
/*** * '抓取二维数组某值出来,到一维数组' * @param $arr * @param $item * @return array */ function get_arr_item_val( ...
- 【k8s label】对node添加删除label,并根据label筛选节点
添加 kubectl label nodes kube-node label_name=label_value kubectl label nodes 1.1.1.1 label_name=label ...
- 怎么改变wampserver默认的网站目录
现在大家基本上开发php的有很大一部分都在用Wampserver,今天来讲讲怎么更改默认的www目录, 需要修改的文件有三个 apache2的配置文件 httpd.conf 和 Wampserver的 ...
- 【Leetcode_easy】852. Peak Index in a Mountain Array
problem 852. Peak Index in a Mountain Array solution1: class Solution { public: int peakIndexInMount ...
- webpack 4 教程
webpack 4 教程:https://blog.zfanw.com/webpack-tutorial/
- 记联想SR850 Raid配置的一个bug
管理raid阵列时,如果要删除某个指定的阵列,则需要选中阵列名而不能选中虚拟磁盘.如果选中的是虚拟磁盘,点击删除后,会删除整个阵列列表里的第一个阵列,而非虚拟磁盘所在的阵列. 过程如下 联想SR850 ...
- git取消追踪本地某个文件
git rm --cached readme1.txt 删除readme1.txt的跟踪,并保留在本地. git rm --f readme1.txt 删除readme1.txt的跟踪,并 ...
- 《ucore lab2》实验报告
资源 ucore在线实验指导书 我的ucore实验代码 练习1:实现 first-fit 连续物理内存分配算法 题目 在实现first fit 内存分配算法的回收函数时,要考虑地址连续的空闲块之间的合 ...
- Node.js安装windows环境
一.安装环境 1.本机系统:Windows 10 Pro(64位)2.Node.js:v6.9.2LTS(64位) 二.安装Node.js步骤 1.下载对应你系统的Node.js版本:https:// ...
- mysql常用系统函数归类
数学函数 函数 作用 ABS(x) 返回x的绝对值 BIN(x) 返回x的二进制(OCT返回八进制,HEX返回十六进制) EXP(x) 返回值e(自然对数的底)的x次方 GREATEST(x1,x2, ...