stone game ii 1140

21 篇文章 0 订阅

leetcode https://leetcode.com/problems/stone-game-ii/

stone game的进阶

递归

public int stoneGameII(int[] piles) {
        int len=piles.length;
        if(len<1)return 0;
        if(len<2)return piles[0];
        int dp[][]=new int[len][len*2];
        int sum[]=new int[len];
        for(int i=len-1;i>=0;i--){
            sum[i]+=(i+1<len?sum[i+1]:0)+piles[i];//代表从i到末尾的数值的和
        }
        return helper(piles,0,1,dp,sum);
    }
    int helper(int piles[],int idx,int M,int [][]dp,int []sum){
        if(idx==piles.length){
            return 0;
        }
        if(piles.length-idx<=2*M)return sum[idx];
        if(dp[idx][M]!=0){
            return dp[idx][M];
        }

        int min=Integer.MAX_VALUE;
        for(int i=1;i<=2*M;i++) {
            min = Math.min(min, helper(piles, idx + i, Math.max(M, i), dp, sum));
        }
        dp[idx][M]=sum[idx]-min;//sum[i]代表第一个人能拿到的最多的石头,min代表的是第二个人拿到最少的石头,所以减一下得到实际能拿到多少
        return dp[idx][M];


    }

动态规划

public:
    int stoneGameII(vector<int>& piles) {
        int len = piles.size();
        vector<vector<int>> dp(len, vector<int>(len, 0));
        vector<int> sum(len, 0);
        // 逆序部分和
        sum.back() = piles.back();
        for(int i=len-2; i>=0; i--) sum[i] = sum[i+1] + piles[i];
        // 倒着查找  dp[i][j] 代表当前在 i 位置,且此时 M = j-1  可以获得的最大收益
        for(int i=len-1; i>=0; i--)
            // 把可能情况都探索一遍,其中 M 的可能大小为 1 到 len
            for(int j=0; j<len; j++){
                // 剩下的点可以一次拿完
                int M = j+1;
                if(2*M >= len-i) dp[i][j] = sum[i];
                else{
                    // 一次拿不完的情况,取最大值
                    for(int k=1; k<=2*M; k++)
                        dp[i][j] = max(dp[i][j], sum[i]-dp[i+k][max(k, M)-1]);
                }
            }
        return dp[0][0];
    }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值