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


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

给你一个整数数组 nums ,如果 nums 至少 包含 2 个元素,你可以执行以下操作中的 任意 一个:

  • 选择 nums 中最前面两个元素并且删除它们。
  • 选择 nums 中最后两个元素并且删除它们。
  • 选择 nums 中第一个和最后一个元素并且删除它们。

一次操作的 分数 是被删除元素的和。

在确保 所有操作分数相同 的前提下,请你求出 最多 能进行多少次操作。

请你返回按照上述要求 最多 可以进行的操作次数。

示例 1:

输入: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:

输入: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

题解:

class Solution {
    /**
        无论减哪两个,中间的序列都是连续的
        nums[0] + nums[1]:dfs(2, n - 1)
        nums[0] + nums[n - 1]:dfs(1, n - 2)
        nums[n - 1] + nums[n - 2]:dfs(0, n - 3)
     */
    int[][] memory;
    int[] nums;
    public int maxOperations(int[] nums) {
        this.nums = nums;
        int n = nums.length;
        memory = new int[n][n];
        // 删除前两个
        int a = clean(2, n - 1, nums[0] + nums[1]);
        // 删除前后各一个
        int b = clean(1, n - 2, nums[0] + nums[n - 1]);
        // 删除后两个
        int c = clean(0, n - 3, nums[n - 1] + nums[n - 2]);
        int res = Math.max(a, Math.max(b, c)) + 1;
        return res;
    }

    public int clean(int i, int j, int temp) {
        for (int k = 0; k < memory.length; k++) {
            Arrays.fill(memory[k], -1);
        }
        return dfs(i, j, temp);
    }

    public int dfs(int i, int j, int temp) {
        // 递归结束条件
        if (i >= j) {
            return 0;
        }
        // 判断对应
        if (memory[i][j] != -1) {
            // 记忆数组索引ij表示在ij情况下取到的最大的次数
            return memory[i][j];
        }
        int res = 0;
        // 删除前两个
        if (nums[i] + nums[i + 1] == temp) {
            res = Math.max(res, dfs(i + 2, j, temp) + 1);
        }
        // 删除前后各一个
        if (nums[i] + nums[j] == temp) {
            res = Math.max(res, dfs(i + 1, j - 1, temp) + 1);
        }
        // 删除后两个
        if (nums[j] + nums[j - 1] == temp) {
            res = Math.max(res, dfs(i, j - 2, temp) + 1);
        }
        return memory[i][j] = res;
    }
}

文章作者: Feliks
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Feliks !
评论
  目录