「LeetCode」486.预测赢家
作者:互联网
'''
「486.预测赢家」
给定一个表示分数的非负整数数组。 玩家 1 从数组任意一端拿取一个分数,随后玩家 2 继续从剩余数组任意一端拿取分数,然后玩家 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 。
「动态规划-博弈问题」
状态变量:dp[i][j] 表示当前玩家在i到j中能拿到的最大分数。
转移方程:
dp[i][j] = max(left,right)
left = nums[i] - dp[i + 1][j]
right = nums[j] - dp[i][j - 1]
初始状态:
dp[i][i] = nums[i](i = 0 ~ n - 1)
'''
nums = list(map(int,input().strip("[]").split(","))) #要用map函数把字符串映射成整数,因为在下面的过程中不能运算字符串
n = len(nums)
dp = [[0]*n for _ in range(n)] #注意在初始化矩阵时候的方法
for i in range(n):
dp[i][i] = nums[i]
for i in range(n - 2,-1,-1):
for j in range(i + 1,n):
left = nums[i] - dp[i + 1][j]
right = nums[j] - dp[i][j - 1]
dp[i][j] = max(left,right)
print(dp[0][n - 1] >= 0)
#心得:思路有了以后代码写起来就快了。这道动态规划问题我第一次运用了dp矩阵,而且循环次序是自低向上的,所以思路在开始的时候并不是那么显而易见。虽然题目不难。希望下次再接触类似这种算法的时候可以更顺利些。
下面是思路的流程图
标签:分数,right,nums,range,玩家,赢家,486,LeetCode,dp 来源: https://blog.csdn.net/lin970113/article/details/116919893