当前位置: 首页 > article >正文

【区间DP】力扣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 {
public:
    int maxOperations(vector<int>& nums) {
        int n = nums.size();
        int memo[n][n];
        auto helper = [&](int i, int j, int target) -> int{
            memset(memo, -1, sizeof(memo));
            function<int(int, int)> dfs = [&](int i, int j) -> int{
                if(i >= j){
                    return 0;
                }

                if(memo[i][j] != -1){
                    return memo[i][j];
                }

                int ans = 0;
                if(nums[i] + nums[i+1] == target){
                    ans = max(ans, 1 + dfs(i+2, j));
                }
                if(nums[j-1] + nums[j] == target){
                    ans = max(ans, 1 + dfs(i, j-2));
                }
                if(nums[i] + nums[j] == target){
                    ans = max(ans, 1 + dfs(i+1, j-1));
                }
                memo[i][j] = ans;
                return ans;
            };
            return dfs(i, j);
        };

        int res = 0;
        res = max(res, helper(0, n - 1, nums[0] + nums[n - 1]));
        res = max(res, helper(0, n - 1, nums[0] + nums[1]));
        res = max(res, helper(0, n - 1, nums[n - 2] + nums[n - 1]));
        return res;
    }
};

我们观察题目可以发现,题目中最多有三种分数,他们取决于第一次操作采用哪一种方式。也就是说如果我们采用回溯的方式,那么我们可以根据第一次操作的方式来分别进行回溯,因为这样子就知道后面回溯的分数要等于多少。

我们定义dfs(i,j)表示下标i到j的nums的相同分数的最大操作数目是多少,也就是说当我们知道我们要使分数为target,那么假设有一种方式nums[i] + nums[i+1] == target,那么这种方式就是可行的,我们继续进行回溯ans = max(ans, 1 + dfs(i+2, j))注:ans是当前dfs的最大操作数目。

我们回溯的界限是当i >= j当时候,返回0,因为已经无法进行任何操作。再加入记忆话搜索的memo就可以减少时间复杂度。


http://www.kler.cn/a/508636.html

相关文章:

  • 在Linux上如何让ollama在GPU上运行模型
  • 函数(函数的概念、库函数、自定义函数、形参和实参、return语句、数组做函数参数、嵌套调用和链式访问、函数的声明和定义、static和extern)
  • PHP智慧小区物业管理小程序
  • 归并排序算法
  • 在 C# 中的Lambda 表达式
  • 【Flink系列】6. Flink中的时间和窗口
  • 被动扫描和主动扫描的区别
  • OSPF(1):基础知识与数据包、状态机、工作过程
  • springboot项目架构
  • 【开源免费】基于Vue和SpringBoot的夕阳红公寓管理系统(附论文)
  • 在VMwareFusion中使用Ubuntu
  • RabbitMQ--发送方确认及消息重试
  • 数仓建模(三)建模三步走:需求分析、模型设计与数据加载
  • (二)异步处理机制(Asynchronous Processing)
  • Spring Boot 中logback无法对warn警告日志发送邮件
  • 使用SIPP发起媒体流性能测试详解
  • PyBroker:利用 Python 和机器学习助力算法交易
  • 自动驾驶占用网格预测
  • Ruby JSON 优化之路:性能提升的探索与实践
  • 文档智能:OCR+Rocketqa+layoutxlm <Rocketqa>
  • 【Kotlin】上手学习之控制流程篇
  • ReaderLM v2:HTML 转 Markdown 和 JSON 的前沿小型语言模型
  • 常见安全风险及防护(如CSRF,XSS) 配置SSL/TLS
  • 分类统计字符个数(PTA)C语言
  • mysql主从复制sql进程中断,报错Tablespace is missing for table ……
  • Vue 3 中的 defineExpose