leetcode3040.相同分数的最大操作数目II

记忆化搜索问题,也可以采用动态规划解决
代码实现时,在计算第二次区间 DP 和第三次区间 DP 时,无需重置 memory 数组,这是因为不同的 target 不会递归到同一对 (i,j) 上。这可以用反证法证明:假如不同的 target 递归到同一对 (i,j) 上,这说明之前的操作次数相同,且删除的元素和相同,所以两次区间 DP 对应的得分是相同的,矛盾。
class Solution {private int[][] memory;private int maxOperations(int[] nums, int start, int end, int target) {//1.元素个数为1甚至更少时,无法进行操作,返回操作数0if (start >= end) {return 0;}//2.如果已经知道start到end需要多少次操作时,直接返回结果if (memory[start][end] != -1) {return memory[start][end];}//3.递归进行计算操作数int result = 0;//3.1删除前两个数result = nums[start] + nums[start + 1] == target ? Math.max(result, 1 + maxOperations(nums, start + 2, end, target)) : result;//3.2删除后两个数result = nums[end - 1] + nums[end] == target ? Math.max(result, 1 + maxOperations(nums, start, end - 2, target)) : result;//3.3删除前后两个数result = nums[start] + nums[end] == target ? Math.max(result, 1 + maxOperations(nums, start + 1, end - 1, target)) : result;//4.记忆化结果并返回return memory[start][end] = result;}public int maxOperations(int[] nums) {//1.初始化记忆数组为全-1memory = new int[nums.length][nums.length];for (int[] ints : memory) {Arrays.fill(ints, -1);}//2.记忆化搜索//2.1删除前两个数int result1 = 1 + maxOperations(nums, 2, nums.length - 1, nums[0] + nums[1]);//2.2删除后两个数int result2 = 1 + maxOperations(nums, 0, nums.length - 3, nums[nums.length - 1] + nums[nums.length - 2]);//2.3删除前后两个数int result3 = 1 + maxOperations(nums, 1, nums.length - 2, nums[0] + nums[nums.length - 1]);//3.返回结果return Math.max(result1, Math.max(result2, result3));}
}