ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

leetcode石子游戏

2022-01-09 09:31:11  阅读:145  来源: 互联网

标签:游戏 int 石子 len 拿走 亚历克斯 leetcode dp


问题:
亚历克斯和李继续他们的石子游戏。许多堆石子 排成一行,每堆都有正整数颗石子 piles[i]。游戏以谁手中的石子最多来决出胜负。

亚历克斯和李轮流进行,亚历克斯先开始。最初,M = 1。

在每个玩家的回合中,该玩家可以拿走剩下的 前 X 堆的所有石子,其中 1 <= X <= 2M。然后,令 M = max(M, X)。

游戏一直持续到所有石子都被拿走。

假设亚历克斯和李都发挥出最佳水平,返回亚历克斯可以得到的最大数量的石头。

示例:
输入:piles = [2,7,9,4,4]
输出:10
解释:
如果亚历克斯在开始时拿走一堆石子,李拿走两堆,接着亚历克斯也拿走两堆。在这种情况下,亚历克斯可以拿到 2 + 4 + 4 = 10 颗石子。
如果亚历克斯在开始时拿走两堆石子,那么李就可以拿走剩下全部三堆石子。在这种情况下,亚历克斯可以拿到 2 + 7 = 9 颗石子。
所以我们返回更大的 10。

思想:

动态规划:我们不仅要存储取到当前堆位置的石子数量还要确定下一次取得的最大值。状态转移方程分两种情况,首先当i+2M>=len时说明剩下的堆数可以都拿走,可以直接赋值。当i+2M<len时我们能拿走的石子数量是前一个人拿走的剩余数量,dp[i][M]=Math.max(dp[i][M],sum-dp[i+x][Math.max(M,x)]);x表示拿走的堆数。

代码:

public int stoneGameII(int[] piles) {
        int len = piles.length;
        int[][] dp = new int[len][len+1];
        int sum = 0;
        int M =1;
        for(int i = len-1;i>=0;i--){
            sum+=piles[i];
            for(M=1;M<=len;M++){
                if(i+2*M >=len) dp[i][M] = sum;
                else{
                    for(int x = 1;x<=2*M;x++){
                        dp[i][M] = Math.max(dp[i][M],sum-dp[i+x][Math.max(M,x)]);
                    }
                }
            }          
        }
        return dp[0][1];
    }

标签:游戏,int,石子,len,拿走,亚历克斯,leetcode,dp
来源: https://blog.csdn.net/jiangzuofengqiao/article/details/122389848

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有