美文网首页
leetcode 877 石子游戏

leetcode 877 石子游戏

作者: jeneen1129 | 来源:发表于2021-06-16 14:32 被阅读0次

游戏描述:
总共偶数堆个石子堆piles[],其中第 i 个石子堆有 piles[i],Alex 和 李 两个玩家参与,每次只能从 数组的头部或者尾部拿取石子堆, 这些石子数总和为奇数 -> 肯定有输赢之分,alex 先拿, 假设两个人都是最佳策略,那么谁会赢?
alex 赢返回 true,李 赢返回 false

游戏示例:

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

解法一: 动态规划
最佳路径类问题的感觉。
分析如下:
如果只剩下一堆石子,就只能取走当前的石子;如果剩下>1堆石子,那么就要从头部或者尾部取走石子,然后另一个玩家取走石子。-> 递归。以 alex 和 李 的 石子数量之差,如果最后总数 > 0 则 alex 赢,反之李赢。
二维数组 dp,行数和列数都为石子的堆数,dp[i][j] 代表 当剩下的石子堆为下标 i - j 时,两个玩家石子数之差的最大值,注意当前玩家不一定是先手 Alex。
其中 i <= j 时,剩下的石子堆才有意义,因此当 i > j 时,dp[i][j] = 0
当 i = j 时,只剩下一堆石子,当玩家只能取走这堆石子,因此对于所有 0 <= i < nums.length,都有 dp[i][j] = dp[i][i] = piles[i]
当 i < j 时,玩家可以选择取走 piles[i] 或者 piles[j],在两种方案中,玩家可以选择 dp[i][j] = max(piles[i] - dp[i+1][j], piles[j] - dp[i][j - 1])

最后判断 dp[0][piles.length - 1] 的值。

var stoneGame = function(piles) {
    const length = piles.length;
    const dp = new Array(length).fill(0).map(() => new Array(length).fill(0));
    for (let i = 0; i < length; i++) {
        dp[i][i] = piles[i];
    }
    for (let i = length - 2; i >= 0; i--) {
        for (let j = i + 1; j < length; j++) {
            dp[i][j] = Math.max(piles[i] - dp[i + 1][j], piles[j] - dp[i][j - 1]);
        }
    }
    return dp[0][length - 1] > 0;
};

优化

var stoneGame = function(piles) {
    const length = piles.length;
    const dp = new Array(length).fill(0);
    for (let i = 0; i < length; i++) {
        dp[i] = piles[i];
    }
    for (let i = length - 2; i >= 0; i--) {
        for (let j = i + 1; j < length; j++) {
            dp[j] = Math.max(piles[i] - dp[j], piles[j] - dp[j - 1]);
        }
    }
    return dp[length - 1] > 0;
};

解法二:数学(脑筋急转弯??)
不管谁是先手,总有人会赢,那么赢的策略(组成堆)肯定是可以确定出来,并且两个玩家都是最佳策略,那么先手只要总是选择数量更多的一组石子就可以总赢。
其中 alex 是先手,那么返回 true

var stoneGame = function(piles) {
    return true;
};

加油!!!!

相关文章

  • leetcode 877 石子游戏

    游戏描述:总共偶数堆个石子堆piles[],其中第 i 个石子堆有 piles[i],Alex 和 李 两个玩家参...

  • 100天代码挑战:DAY10

    LeetCode 877. 石子游戏 亚历克斯和李用几堆石子在做游戏。偶数堆石子排成一行,每堆都有正整数颗石子 p...

  • LeetCode 877. 石子游戏

    1、题目 877. 石子游戏 2、题解 首先,一开始我觉得这道题目并不严谨。因为我大略感觉到先手选择的人就能赢得这...

  • Leetcode 877. 石子游戏

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

  • LeetCode-python 877. 石子游戏

    题目链接难度: 中等 类型:动态规划 亚历克斯和李用几堆石子在做游戏。偶数堆石子排成一行,每堆都...

  • T877、石子游戏

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

  • 877.石子游戏(中等)

    参考:https://labuladong.gitbook.io/algo/mu-lu-ye-2/mu-lu-ye...

  • 5627. 石子游戏 VII(区间dp)

    5627. 石子游戏 VII[https://leetcode-cn.com/problems/stone-gam...

  • Leetcode 877 StoneGame

    解题方案1: 整理一下规则:Alex、Lee两个人,Alex先手,Lee后手。每次只能拿 第一堆 或者 最后一堆两...

  • 486预测赢家-877石子游戏(区间dp)

    这是一道区间dp的问题,我们可以先用递归的方法求解。 intchooseStart=nums[start]-dfs...

网友评论

      本文标题:leetcode 877 石子游戏

      本文链接:https://www.haomeiwen.com/subject/linxyltx.html