zoukankan      html  css  js  c++  java
  • 力扣486-预测赢家-(dp)

    https://leetcode-cn.com/problems/predict-the-winner

    题意:给一个长度为n的正数数组a,两个人轮流取数,每人每次可以在左右两端取一个数字,谁累计得多谁赢。判断先手是否能赢。

    思路:

    设自己的收益为x,别人的收益为y,纯收益就是x-y,如果纯收益大于0,就能赢。

    贪心取最大值显然不行,(6,100,1,1)这样先手先取第一个就GG了。

    对一段数,区间[i,j]每取一个数,不论是哪边,都会对后面造成影响。

    取了i,收益a[i],剩下[i+1,j]给对方取。

    取了j,收益a[j],剩下[i,j-1]给对方取。

    如果只有1个数,那么选取的人 的最大收益 是一定的

    如果只有2个数,一人一个,先手的最大收益也是一定的,纯收益=max-min。

    如果有3个数,不论先选哪一个,后手选的时候只剩2个数,后手的最大收益也是一定的,第三次操作的收益也是固定的。

    由此可见,对于每一种情况都可以逆推回来。

    dp[i][j]表示 当前选手(无论是谁)对区间[i,j]能够获得的最大收益。

    选取i,dp[i][j]=a[i]-dp[i+1][j];

    选取j,dp[i][j]=a[j]-dp[i][j-1];

    从i+1和j-1可以知道,双重循环i递增,j递减。

    class Solution {
        public boolean PredictTheWinner(int[] a) {
            int[][] dp=new int[25][25];
            int n=a.length-1;
            for(int i=n;i>=0;i--){//下面需要利用到i+1,所以i要从大到小
                for(int j=i+1;j<=n;j++){//下面利用到j-1,所以j从小到大
                    //区间[i,j]
                    int x=a[i]-dp[i+1][j];//取i
                    int y=a[j]-dp[i][j-1];//取j
                    dp[i][j]=Math.max(x,y);
                }
            }
            if(dp[0][n]>=0)
                return true;
            else 
                return false;
        }
    }
  • 相关阅读:
    课后作业成绩汇总
    关于作业提交要求声明 2017-09-22
    团队编程项目作业成绩汇总
    结对项目作业成绩汇总
    团队组信息
    小知识记录:第XI篇
    小知识记录:第X篇
    小知识记录:第十二篇
    小知识记录:第十一篇
    小知识记录:第十篇
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/12644067.html
Copyright © 2011-2022 走看看