首页 > 试题广场 >

删除相邻数字的最大分数

[编程题]删除相邻数字的最大分数
  • 热度指数:441 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个长度为 n 的仅包含正整数的数组,另外有一些操作,每次操作你可以选择数组中的任意一个元素 ,同时数组中所有等于 的元素会被全部移除,同时你可以得到 分,直到所有的元素都被选择或者删除。
请你计算最多能得到多少分。

数据范围: 数组长度满足 ,数组中的元素大小都满足
示例1

输入

[1,2]

输出

2

说明

直接选择元素 2 ,然后 1 被同时移除。
示例2

输入

[1,2,3]

输出

4

说明

先选择 3 ,同时 2 被移除,再选择 1 ,即得到 4 分。
示例3

输入

[1,2,1,3,2,2,2,2,3]

输出

10

说明

第一步选择一个 2 ,然后所有 1 和 3 都被移除了,此时数组中剩下的是 [2,2,2,2] ,依次选择他们即可得到 10 分
import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param a int整型ArrayList 
     * @return int整型
     */
    public int boredom (ArrayList<Integer> a) {
        // write code here
        Map<Integer, Integer> map = new HashMap<>();
        for(int aa : a){
            map.put(aa, map.getOrDefault(aa, 0) +aa);
        }
        List<Integer> list = new ArrayList<>();
        list.addAll(map.keySet());
        Collections.sort(list);
        
        int[][] dp = new int[2][list.size()];
        dp[0][0]=0;
        dp[1][0]=map.get(list.get(0));
        for(int i=1;i<list.size();i++){
            int cur = list.get(i);
            //不选择此元素
            dp[0][i]=Math.max(dp[0][i-1], dp[1][i-1]);
            //选择此元素
            if(list.get(i-1)==cur-1){
                dp[1][i]=i-2>=0?Math.max(dp[0][i-2], dp[1][i-2])+map.get(cur) : 0+map.get(cur);
            }else{
                dp[1][i]=i-2>=0?Math.max(dp[0][i-1], dp[1][i-1])+map.get(cur) : 0+map.get(cur);
            }

        }

        return Math.max(dp[0][list.size()-1], dp[1][list.size()-1]);
    }
}

发表于 2022-11-23 12:14:47 回复(0)
    public int boredom (ArrayList<Integer> a) {
        // write code here
        Collections.sort(a);
        Map<Integer, Integer> map = new HashMap<>();
        ArrayList<Integer> b = new ArrayList<>();
        for(int x : a) {
            if(b.size() > 0 && b.get(b.size()-1) == x) {
                map.put(x, map.get(x) + x);
                continue;
            }
            b.add(x);
            map.put(x, x);
        }
        int[] dpl = new int[b.size()];
        int[] dpr = new int[b.size()];
        int[] max = new int[b.size()];
        max[0] = map.get(b.get(0));
        for(int i = 1; i < b.size(); ++i) {
            dpl[i] = b.get(i-1)+1 == b.get(i) ? i >= 2 ? max[i-2] : 0 : max[i-1];
            max[i] = Math.max(max[i-1], dpl[i] + map.get(b.get(i)));
        }
        Arrays.fill(max, 0);
        max[b.size()-1] = map.get(b.get(b.size()-1));
        for(int i = b.size()-2; i >= 0; --i) {
            dpr[i] = b.get(i+1)-1 == b.get(i) ? i < b.size()-2 ? max[i+2] : 0 : max[i+1];
            max[i] = Math.max(max[i+1], dpr[i] + map.get(b.get(i)));
        }
        int ans = 0;
        for(int i = 0; i < b.size(); ++i) {
            ans = Math.max(ans, dpl[i] + dpr[i] + map.get(b.get(i)));
        }
        return ans;
    }
dpl[i]:只考率a[0..i]这个子数组,拿掉a[i]的情况下的最高得分(不包含a[i])
dpr[i]:只考虑a[i..n]这个子数组,拿掉a[i]的情况下的最高得分(不包含a[i])
ans = max{dpl[i] + dpr[i] + a[i]}
发表于 2022-03-03 13:48:21 回复(0)