import java.util.*; /** * NC300 删除相邻数字的最大分数 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * 相似 => NC176 打家劫舍(一) * @param a int整型ArrayList * @return int整型 */ public int boredom (ArrayList<Integer> a) { // return solution1(a); return solution2(a); // return solution3(a); } /** * 动态规划 * * dp[i][0]表示第i种数字不选择时能得到的最多分数 * dp[i][1]表示第i种数字要选择时能得到的最多分数 * * dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]) * { dp[i-1][0] + map.get(curr) , pre+1 == curr * dp[i][1] = { * { Math.max(dp[i-1][0], dp[i-1][1]) + map.get(curr) , pre+1 != curr * * @param a * @return */ private int solution1(ArrayList<Integer> a){ // 保证有序 TreeSet<Integer> set = new TreeSet<Integer>(); // 存储分数 HashMap<Integer, Integer> map = new HashMap<>(); for(int num: a){ set.add(num); map.put(num, map.getOrDefault(num,0)+num); } int len = set.size(); int[][] dp = new int[len+1][2]; // 前面数字 int pre=-1; // 当前数字 int curr; for(int i=1; i<=len; i++){ curr = set.pollFirst(); dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1]); if(pre+1 == curr){ dp[i][1] = dp[i-1][0] + map.get(curr); }else{ dp[i][1] = Math.max(dp[i-1][0], dp[i-1][1]) + map.get(curr); } pre = curr; } return Math.max(dp[len][0], dp[len][1]); } /** * 动态规划 * * dp[i]表示到达数字i时能得到的最多分数 * * dp[i] = Math.max(dp[i-1], dp[i]+dp[i-2]) * * @param a * @return */ private int solution2(ArrayList<Integer> a){ int max = 0; for(int num: a){ max = Math.max(max, num); } // init int[] dp = new int[max+1]; for(int num: a){ dp[num] += num; } for(int i=2; i<=max; i++){ dp[i] = Math.max(dp[i-1], dp[i]+dp[i-2]); } return dp[max]; } /** * 动态规划 * * dp[i]表示到达数字i时能得到的最多分数 * * dp[i] = Math.max(dp[i-1], dp[i]+dp[i-2]) * * @param a * @return */ private int solution3(ArrayList<Integer> a){ int max = 10000; // init int[] dp = new int[max+1]; for(int num: a){ dp[num] += num; } for(int i=2; i<=max; i++){ dp[i] = Math.max(dp[i-1], dp[i]+dp[i-2]); } return dp[max]; } }