Leetcode—stonegames(2)

1140. Stone Game II--✖️

class Solution {
    Integer[][] cache; // integer 后面才可以判空,应用数据类型默认值为null,基本数据类型默认值就是基本数据类型的默认值
    public int stoneGameII(int[] piles) {
        cache = new Integer[piles.length][piles.length * 2];
        int totalStones = 0;
        for(int stone : piles) {
            totalStones += stone;
        }
        //(Alice's Stone + Bob's Stone) = totalStones
        //(Alice's Stone - Bob's Stone) = Alice's score
        // 2 * Alice's Stone = totalStones + Alice's score
        //Alice's Stone      = (totalStones + Alice's score) / 2
        return (totalStones + getAliceScore(piles, 0, 1)) / 2;
    }
    private int getAliceScore(int[] piles, int index, int M) {
        if(index == piles.length) {
            return 0;
        }
        if(cache[index][M] != null) {
            return cache[index][M];
        }
        int maxScore = Integer.MIN_VALUE;
        int stone = 0;
        for(int x = 0; x < 2 * M; x++) {
            int i = index + x;
            if(i >= piles.length) {
                continue;
            }
            stone += piles[i];
            int score = stone - getAliceScore(piles, i + 1, Math.max(x + 1, M));
            maxScore = Math.max(maxScore, score);
        }
        return cache[index][M] = maxScore;
    }
}

877. Stone Game

class Solution {
    public boolean stoneGame(int[] piles) {
        int n = piles.length;
        // dp[i][j] 表示在石头堆的第 i 到第 j 堆中,当前玩家与对手的得分差
        int dp[][] = new int[n][n];
        for(int i = 0; i < n; i++) {
            // 只有一堆时,对角线上的元素
            dp[i][i] = piles[i];
        }
        // 外层循环 l 表示石头堆的数量范围,从2开始,即从两堆石头开始考虑
        for(int l = 2; l <= n; l++) {
            //  内层循环 i 表示石头堆的起始位置
            for(int i = 0; i + l - 1 < n; i++) {
                int j = i + l - 1; //计算当前范围的结束位置
                int a = piles[i] - dp[i + 1][j]; // 假设从i堆开始
                int b = piles[j] - dp[i][j - 1]; // 假设从j堆开始
                dp[i][j] = Integer.max(a, b);
            }
        }
        return dp[0][n - 1] > 0;
    }
}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值