3040. 相同分数的最大操作数目 II(1709)
给你一个整数数组 nums
,如果 nums
至少 包含 2
个元素,你可以执行以下操作中的 任意 一个:
- 选择
nums
中最前面两个元素并且删除它们。
- 选择
nums
中最后两个元素并且删除它们。
- 选择
nums
中第一个和最后一个元素并且删除它们。
一次操作的 分数 是被删除元素的和。
在确保 所有操作分数相同 的前提下,请你求出 最多 能进行多少次操作。
请你返回按照上述要求 最多 可以进行的操作次数。
示例 1:
1 2 3 4 5 6 7
| 输入:nums = [3,2,1,2,3,4] 输出:3 解释:我们执行以下操作: - 删除前两个元素,分数为 3 + 2 = 5 ,nums = [1,2,3,4] 。 - 删除第一个元素和最后一个元素,分数为 1 + 4 = 5 ,nums = [2,3] 。 - 删除第一个元素和最后一个元素,分数为 2 + 3 = 5 ,nums = [] 。 由于 nums 为空,我们无法继续进行任何操作。
|
示例 2:
1 2 3 4 5 6
| 输入:nums = [3,2,6,1,4] 输出:2 解释:我们执行以下操作: - 删除前两个元素,分数为 3 + 2 = 5 ,nums = [6,1,4] 。 - 删除最后两个元素,分数为 1 + 4 = 5 ,nums = [6] 。 至多进行 2 次操作。
|
提示:
2 <= nums.length <= 2000
1 <= nums[i] <= 1000
(爆内存)区间dp:递推3维数组写法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public int maxOperations(int[] nums) { int n = nums.length; int f[][][] = new int[n+1][n+1][2001]; int res = 0; for (int i = n-2; i >= 0; i--) { for (int j = i+1; j < n; j++) { int head = nums[i] + nums[i+1]; int tail = nums[j] + nums[j-1]; int mid = nums[i] + nums[j]; f[i][j][head] = Math.max(f[i][j][head], f[i+2][j][head] + 1); f[i][j][tail] = Math.max(f[i][j][tail], (j-2 >= 0 ? f[i][j-2][tail] : 0) + 1); f[i][j][mid] = Math.max(f[i][j][mid], f[i+1][j-1][mid] + 1); if (i == 0 && j == n-1) { res = Math.max(res, f[i][j][head]); res = Math.max(res, f[i][j][tail]); res = Math.max(res, f[i][j][mid]); } } } return res; } }
|
区间dp:递推,2维数组,并不需要第3维,因为删除元素和最多只有3种情况,依次考虑即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public int maxOperations(int[] nums) { int n = nums.length; int target[] = new int[3]; target[0] = nums[0] + nums[1]; target[1] = nums[n-1] + nums[n-2]; target[2] = nums[0] + nums[n-1]; int res = 0; for (int tg : target) { int f[][] = new int[n+1][n+1]; for (int i = n-2; i >= 0; i--) { for (int j = i+1; j < n; j++) { int head = nums[i] + nums[i+1]; int tail = nums[j] + nums[j-1]; int mid = nums[i] + nums[j]; if (head == tg) f[i][j] = Math.max(f[i][j], f[i+2][j] + 1); if (tail == tg) f[i][j] = Math.max(f[i][j], (j-2 >= 0 ? f[i][j-2] : 0) + 1); if (mid == tg) f[i][j] = Math.max(f[i][j], f[i+1][j-1] + 1); } } res = Math.max(res, f[0][n-1]); } return res; } }
|