【Leetcode每日笔记】877. 石子游戏/486. 预测赢家(Python)

文章目录

  • 题目
  • 解题思路
    • 动态规划
      • 状态定义
      • 状态转移方程
    • 我是傻*
  • 代码

题目

这两道题的解题思路是一样的。

877.石子游戏

亚历克斯和李用几堆石子在做游戏。偶数堆石子排成一行,每堆都有正整数颗石子 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 。

提示:

2 <= piles.length <= 500
piles.length 是偶数。
1 <= piles[i] <= 500
sum(piles) 是奇数。

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 仍为赢家。

解题思路

动态规划

解读:题目要求每个玩家,只能从当前数组开头或者结尾取,也就是说子数组一定是连续的,相对原数组而言不会出现断层。

状态定义

定义二维数组 dp,其行数和列数都等于石子的堆数,dp[i][j] 表示当剩下的石子堆为下标 i 到下标 j 时,当前玩家与另一个玩家的石子数量之差的最大值,注意当前玩家不一定是先手 Alex。

状态转移方程

只有当i<=j时,剩下的石子堆才有意义,因此当i>j时,dp[i][j]=0;
当i=j,只剩下一堆石子,当前玩家只能取走这堆石子,因此对于所有0≤i≤len(nums),都有dp[i][j]=nums[i];
当idp[i][j]=max(nums[i]-dp[i+1][j],nums[j]-dp[i][j-1]),最后判断dp[0][-1]的值,如果大于0,则Alex的石子数量大于Lee的,返回True,否则返回False。
【Leetcode每日笔记】877. 石子游戏/486. 预测赢家(Python)_第1张图片

我是傻*

总是先手的赢。。。

代码

class Solution:
    def stoneGame(self, piles: List[int]) -> bool:
        l = len(piles)
        dp = [[0]*l for _ in range(l)]
        for i in range(l):
            dp[i][i] = piles[i]
        for i in range(l-2,-1,-1):
            for j in range(i+1,l):
                dp[i][j] = max(piles[i]-dp[i+1][j],piles[j]-dp[i][j-1])
        return dp[0][-1]>=0
class Solution:
    def stoneGame(self, piles: List[int]) -> bool:
        return True

你可能感兴趣的:(LeetCode一周一结,#,动态规划,算法,动态规划,leetcode,python,智商堪忧)