zoukankan      html  css  js  c++  java
  • 740. Delete and Earn

     1  /*
     2     这个题的关键在于:要想达到最好的结果,每次都应该选取合适的数,当选取一个数时由于要考虑它两边的数,所以我们采取装桶法,
     3     这样就知道数组中所有这个数相加的和(也就是当选取一个数时会获得的利益,和抛弃一个数时的损失),同时也相当于桶排序了,可以直接表示出i相邻的数。
     4     转化为子问题,子问题就是子序列,最小的子序列就是只有一个数,最大的子序列就是所有数,也就是最后答案,我们一个一个加
     5     新序列就是原序列添加一个数,这里我们倒着考虑,从最后一个数往前添加,假设原序列的最好结果是dp[i+1],那么新序列生成后,
     6     有两种情况,就是新添加的数取不取,对应状态方程就是:
     7     dp[i] = Math.max(valus[i]+dp[i-2],dp[i-1]),括号中第一个选项是取新数,这样的话i+1就不能取,新的结果就是现在的数加上i+2的情况,
     8     这里能直接使用dp[i+2]是因为i+1不取,所以i+2可以任选取不取,符合使用条件。
     9     如果不取新数,那么现在的状态就是dp[i+1]
    10      */
    11     public int deleteAndEarn(int[] nums) {
    12         //假设有很多桶,数组中的每个数就是桶的编号,桶里装的就是数组中所有等于桶编号的数的和
    13         int[] dp = new int[10003];
    14         int[] valus = new int[10001];
    15 
    16         //装桶环节
    17         for(int num : nums)
    18         {
    19             valus[num] += nums[num];
    20         }
    21         //
    22         for(int i = 2;i < 10003;i++)
    23         {
    24             //dp[i]记录倒着数,到i位置处的子序列的最好结果是什么,注意这里dp[i]产生的条件是不考虑前边,也就是i-1处桶,以后要用到的话,也要保证i-1处桶不用才能成立
    25             //状态方程:考虑要不要i桶,不要的话,dp[i+1]满足成立条件,此时的最好情况也就是dp[i+1]。如果要i,那么i+1不能要,但是dp[i+2]满足成立条件
    26             //最好的结果就是valus[i]+dp[i+2]
    27             dp[i] = Math.max(valus[i]+dp[i-2],dp[i-1]);
    28         }
    29     return dp[10002];
    30     }
  • 相关阅读:
    实验 6 数组1输出最大值和它所对应的下标
    实验5第二题
    实验5第一题
    作业 3 应用分支与循环结构解决问题 判断是否闰年
    心得与体会1
    第七章
    第六章
    第五章
    第四章
    第一章
  • 原文地址:https://www.cnblogs.com/stAr-1/p/7989860.html
Copyright © 2011-2022 走看看