数据结构与算法-动态规划-区间dp(石子合并,环形石子合并,凸多边形的划分,加分二叉树,棋盘分割)

news2025/2/13 6:05:32

概念

区间动态规划(Interval Dynamic Programming)是动态规划的一个分支,它在处理一些与区间相关的最优解问题上非常有效。以下从基本概念、解题步骤、经典例题、优缺点等方面为你详细介绍:

基本概念:区间 DP 的核心思想是将问题划分为不同长度的区间,通过求解小区间的最优解,逐步合并得到大区间的最优解。它通常用于解决一类可以将问题分解为若干相互关联的子区间问题,并且这些子区间的最优解可以通过更小的子区间的最优解推导出来的问题。

解题步骤

定义状态:通常用 (dp[i][j]) 表示区间 ([i, j]) 上的某种最优值,比如 (dp[i][j]) 可以表示从下标 (i) 到 (j) 的元素进行某种操作所得到的最大收益、最小花费等。

状态转移方程:这是区间 DP 的关键。它描述了如何从较小的区间的最优解得到较大区间的最优解。例如,对于一个表达式求值问题,可能有 (dp[i][j] = max{dp[i][k] + dp[k + 1][j] + text{合并操作}(i, k, j)}),其中 (i leq k < j),即通过枚举区间 ([i, j]) 内的分割点 (k),将区间 ([i, j]) 拆分成两个子区间 ([i, k]) 和 ([k + 1, j]),然后根据具体问题的要求进行合并操作。

初始化:一般需要初始化长度为 1 的区间,即 (dp[i][i]) 的值,这通常根据问题的具体情况来确定。例如在某些问题中, (dp[i][i]) 可能表示单个元素的某种属性值。

计算顺序:按照区间长度从小到大的顺序进行计算。先计算长度为 2 的区间的 (dp) 值,再计算长度为 3 的区间,以此类推,直到计算出长度为 (n)(问题规模)的区间的 (dp) 值。这样可以保证在计算较大区间时,其所依赖的小区间的最优解已经计算出来。

引例(石子合并):

分析:

有 (N) 堆排成一排的石子,每堆石子质量用整数表示,要求将这 (N) 堆石子合并成一堆。合并规则是每次只能合并相邻的两堆,合并代价为两堆石子质量之和,且合并顺序不同,总代价不同,目标是找出总代价最小的合并方法并输出最小代价。

状态定义:使用二维数组 (dp[i][j]) 表示将第 (i) 堆石子到第 (j) 堆石子合并成一堆的最小代价。其中 (i) 和 (j) 分别表示区间的起始和结束位置,(1<=i<= j<= N)。

状态转移方程:通过枚举区间 ([i, j]) 内的分割点 (k)((i<=k < j)),将区间 ([i, j]) 拆分成 ([i, k]) 和 ([k + 1, j]) 两个子区间。状态转移方程为 (dp[i][j]=min{dp[i][k]+dp[k + 1][j]+sum_{s = i~j} a[s]}) 。其中 (sum_{s = i~j}a[s]) 是将第 (i) 堆到第 (j) 堆石子合并成一堆时这一次合并的代价,(a[s]) 表示第 (s) 堆石子的质量。

初始化:当 (i = j) 时,即只有一堆石子,不需要合并,所以 (dp[i][i]=0) 。

(注意,这里的是相邻的两个石子合并,不是任意两个石子合并,如果是任意两个就变成霍夫曼树题了)

思路

伪代码:

习题1(环形区间dp)环形石子合并:

分析:

这是一个环形石子合并问题,是在直线石子合并基础上的拓展,属于区间动态规划范畴。以下从题目条件、解题关键、解题思路等方面介绍:

有 (n) 堆石子绕圆形操场排放,需将它们有序合并成一堆。

每次只能合并相邻的两堆,合并新堆的石子数作为此次合并的得分。

要求编写程序,读入堆数 (n) 及每堆石子数,计算出 (n - 1) 次合并得分总和最大与最小的方案对应的得分。

1先将环形石子堆转化为直线石子堆(复制一份接到原序列后)。

2计算区间长度为 2 的 (maxdp) 和 (mindp) 值,即相邻两堆石子合并的得分情况。

3按照区间长度从小到大的顺序计算 (maxdp) 和 (mindp) 值,例如从长度为 3 的区间开始,依次计算到长度为 (n) 的区间。

4因为环形的特性,在长度为 (n) 的区间中,找出所有满足条件的 (maxdp[i][i + n - 1]) 中的最大值作为合并得分总和的最大值,找出所有 (mindp[i][i + n - 1]) 中的最小值作为合并得分总和的最小值。

破环为链有2个做法:

我们已知的一般区间dp的时间复杂度是n^3,枚举缺口也是n种,这样的时间复杂度就是n^4,太高了,再看看第二种,我们只需要处理2n的一个序列就好了,之后枚举长度为n的答案,这样的时间复杂度只有8*n^3.

伪代码:

习题2(环形区间dp)能量链条:
 

分析:
这是一道基于区间动态规划的问题,关键在于找出能量珠聚合的最优顺序以获取最大总能量。以下从题目条件、解题思路、关键步骤等方面进行分析:

能量珠特性:在 Mars 星球上,每个 Mars 人有一串含 (N) 颗能量珠的项链。能量珠有头标记和尾标记,且相邻珠子前一颗的尾标记等于后一颗的头标记,这是珠子能够聚合的前提条件。

聚合规则与能量计算:当两颗相邻珠子聚合时,若前一颗头标记为 (m),尾标记为 (r),后一颗头标记为 (r),尾标记为 (n),则聚合释放能量为 (m* r* n)(Mars 单位),新珠子头标记为 (m),尾标记为 (n)。

目标:设计聚合顺序,使项链释放的总能量最大。

破环为链:将长度为 (N) 的环形能量珠序列复制一份接到原序列后面,形成长度为 (2N) 的直线序列,以便在直线序列上进行区间 DP 计算来覆盖环形结构的所有聚合情况。

计算区间 DP 值:按照区间长度从小到大的顺序计算 (dp) 值。先计算长度为 2 的区间(即两颗相邻能量珠聚合的情况),再逐步计算长度更大的区间,直至长度为 (N) 的区间。

获取结果:在长度为 (N) 的区间中,找出所有 (dp[i][i + N - 1]) 中的最大值,即为这串项链能释放的最大总能量。

伪代码:

习题3(高精度+区间dp)凸多边形的划分:

分析:

给定有 (N) 个顶点且顶点有权值的凸多边形,目标是找出一种将其划分为 (N - 2) 个互不相交三角形的方式,使得这些三角形顶点权值乘积之和最小。由于划分方式众多,直接枚举所有情况时间复杂度高,所以适合用动态规划求解。

合理枚举中间顶点:在状态转移时,准确枚举中间顶点 (k) 来划分凸多边形,从而得到子问题的最优解并推导出原问题的最优解。

划分示意图:

思路:

伪代码:

因为这个题目的数据量过大,要使用高精度算法:

下面实现高精度加法乘法,和大数字的比较

代码主体:

习题4(树+区间dp)加分二叉树:

分析:

二叉树遍历特征:给定二叉树的中序遍历为 (1, 2, 3, cdots, n) ,这一条件限制了二叉树节点的相对位置关系。因为中序遍历的特点是左 - 根 - 右,所以若确定某节点 (k) 为根节点,那么其左子树节点编号范围是 (1) 到 (k - 1) ,右子树节点编号范围是 (k + 1) 到 (n) ,这为后续动态规划中对问题的划分提供了依据。

节点分数与加分规则:每个节点都有一个正整数分数 (d_i) 。二叉树及其子树的加分计算规则为:子树的左子树加分 × 右子树加分 + 子树的根的分数,并且规定空子树加分是 (1) ,叶子节点的加分就是其自身分数。此规则明确了不同结构二叉树的加分计算方式,是动态规划中状态转移的基础。

计算 (dp) 值:按照区间长度从小到大的顺序依次计算 (dp) 值。先计算长度为 (1) 的区间(即单个节点情况),然后计算长度为 (2) 的区间(两个节点构成简单二叉树情况),以此类推,直到计算出长度为 (n) 的区间(整个二叉树)的 (dp) 值。最终 (dp[1][n]) 就是所求二叉树的最高加分。

记录根节点信息:在计算 (dp) 值的过程中,同时记录每个区间 ([i, j]) 对应的使得加分最高的根节点 (root[i][j]) 。这一步是为了后续能够通过回溯构建出最优二叉树,进而得到其前序遍历。

回溯求前序遍历:从记录的 (root[1][n]) 开始回溯。先输出根节点编号,然后对左子树(对应区间 ([1, root[1][n] - 1]) )和右子树(对应区间 ([root[1][n] + 1, n]) )递归进行同样的操作,从而得到二叉树的前序遍历序列。

伪代码:
g是i到j元素的根

f是dp数组

先实现一个dfs前序遍历的函数

然后是代码主体

习题5(二维区间dp)棋盘分割:

分析:

棋盘与分割规则:给定一个 (8×8) 的棋盘,每次分割需割下一块矩形棋盘且使剩余部分也是矩形,且只能沿棋盘格子的边进行,经过 ((n - 1)) 次分割后得到 (n) 块矩形棋盘。

分值与目标:棋盘上每格有一个分值,矩形棋盘总分是其所含各格分值之和。要求计算出分割成 (n) 块矩形棋盘后,各矩形棋盘总分均方差的最小值。均方差的化简

预处理棋盘,计算出每个子矩形棋盘的总分,可通过前缀和的方式快速计算。

按照分割块数 (m) 从小到大、矩形棋盘大小从小到大的顺序计算 (dp) 值。

最终 (dp[1][1][8][8][n]) 即为将整个 (8×8) 棋盘分割成 (n) 块时均方差的最小值。

思路:

伪代码:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2297194.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

32单片机学习记录4之串口通信

32单片机学习记录4之串口通信 前置 STM32的GPIO口有通用模式&#xff0c;复用模式&#xff0c;模拟模式三种&#xff0c;加上输入输出就是有6中对应的模式。 我学习了通用模式&#xff0c;会使用GPIO口使用一些简单外设&#xff0c;如LED&#xff0c;独立按键&#xff0c;红外…

开源、免费项目管理工具比较:2025最新整理30款

好用的开源、免费版项目管理系统有&#xff1a;1.Redmine&#xff1b;2. Taiga&#xff1b;3. OpenProject&#xff1b; 4.ProjectLibre&#xff1b; 5.GanttProject&#xff1b; 6.Tuleap&#xff1b; 7.Trac&#xff1b;8. Phabricator&#xff1b; 9.Notion&#xff1b; 10.…

Android10 音频参数导出合并

A10 设备录音时底噪过大&#xff0c;让音频同事校准了下&#xff0c;然后把校准好的参数需要导出来&#xff0c;集成到项目中&#xff0c;然后出包&#xff0c;导出方式在此记录 设备安装debug系统版本调试好后&#xff0c; adb root adb remount adb shell 进入设备目录 导…

在 Azure 上部署 DeepSeek 并集成 Open WebUI

DeepSeek 是杭州深度求索人工智能基础技术研究有限公司发布的开源大模型&#xff0c;最近是持续火爆&#xff0c;使得官方服务经常不可用。网上各种本地部署和私有部署的文章已经很多&#xff0c;这里我们提供一个全部基于 Azure 的私有部署方案。 使用 Azure AI Foundry 部署…

Springboot整合支付宝支付

支付宝支付功能 步骤一&#xff1a;沙箱配置支付宝沙箱配置 步骤二&#xff1a;使用内网穿透步骤三&#xff1a;开始对接SDK配置文件支付 步骤一&#xff1a;沙箱配置 支付宝沙箱配置 需要有支付宝沙箱&#xff1a;提供一个虚拟的支付环境&#xff0c;用于测验调试&#xff0…

deepseek+kimi一键生成PPT

1、deepseek生成大纲内容 访问deepseek官方网站&#xff1a;https://www.deepseek.com/ 将你想要编写的PPT内容输入到对话框&#xff0c;点击【蓝色】发送按钮&#xff0c;让deepseek生成内容大纲&#xff0c;并以markdown形式输出。 等待deepseek生成内容完毕后&#xff0c…

基于ssm的超市订单管理系统

一、系统架构 前端&#xff1a;jsp | web components | jquery | css | ajax 后端&#xff1a;spring | springmvc | mybatis 环境&#xff1a;jdk1.8 | mysql | maven | tomcat 二、代码及数据 三、功能介绍 01. 登录 02. 首页 03. 订单管理 04. 供应…

AnyPlace:学习机器人操作的泛化目标放置

25年2月来自多伦多大学、Vector Inst、上海交大等机构的论文“AnyPlace: Learning Generalized Object Placement for Robot Manipulation”。 由于目标几何形状和放置的配置多种多样&#xff0c;因此在机器人任务中放置目标本身就具有挑战性。为了解决这个问题&#xff0c;An…

【DeepSeek】在本地计算机上部署DeepSeek-R1大模型实战(完整版)

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能&#xff08;AI&#xff09;通过算法模拟人类智能&#xff0c;利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络&#xff08;如ChatGPT&…

基于全志T507的边缘计算机,推动光伏电站向智能运维转型

智能监控与维护 光伏电站通常分布在广阔的地域内&#xff0c;传统的监控方式往往需要大量的人力物力进行现场检查和数据采集。采用全志T507为核心的嵌入式工控机或边缘计算控制器可以实现光伏电站的实时监测&#xff0c;通过连接传感器网络收集电站各个组件的工作状态信息&…

用户认证练习实验

一.拓扑 二.sw2配置 三.ip配置 四.dhcp分配IP地址 五.安全区域配置 六.防火墙地址组信息 七.管理员 创建管理员角色 创建管理员 启动tenlnet 八.用户认证配置 认证策略 九.安全策略配置

【登录认证】

目录 一. 会话技术1.1 cookie1.2 session1.3 令牌方案 二. JWT令牌三. 过滤器Filter四. 拦截器Interceptor \quad 一. 会话技术 \quad \quad 1.1 cookie \quad \quad 1.2 session \quad \quad 1.3 令牌方案 \quad \quad 二. JWT令牌 \quad \quad 三. 过滤器Filter \quad \quad …

DeepSeek 赋能智慧教育 | 讯方“教学有方”大模型全面接入 DeepSeek!

国产 DeepSeek 大模型以强大的深度学习能力和广泛应用场景迅速火爆全球&#xff0c;其在智能对话、文本创作、语义解析、计算推理、代码生成与补全等多个应用领域&#xff0c;展现出了无与伦比的实力和魅力。2月10日 &#xff0c;由讯方技术自研的教育行业大模型“教学有方”全…

Unity中自定义协程的简单实现

在 Unity 中&#xff0c;协程&#xff08;Coroutine&#xff09;是一种非常强大的工具&#xff0c;它允许我们在不阻塞主线程的情况下&#xff0c;将代码的执行分成多个步骤&#xff0c;在不同的帧中执行。 Unity中协程实现原理 迭代器与状态机&#xff1a;本质上是基于C#的迭…

打开Visual Studio Code的时候发现未检测到适用于linux的windows子系统,那么该问题要如何解决?

两个月没有使用vscode编写代码&#xff0c;今天使用的时候发现了以上的问题导致我的vscode无法编写程序&#xff0c;接下来我将本人解决该问题的思路分享给大家。 首先我们要清楚WSL是适用于linux的window的子系统&#xff0c;是一个在Windows 10\11上能够运行原生Linux二进制可…

Linux(socket网络编程)TCP连接

Linux&#xff08;socket网络编程&#xff09;TCP连接 基础文件目录函数系统进程控制函数fork()exec系列函数void abort(void)void assert(int expression)void exit(int status)void _exit(int status)int atexit(void (*func)(void))int on_exit(void (*function)(int,void*)…

Rust学习总结之所有权(一)

不管是计算机的哪种语言&#xff0c;都有内存的管理方式。主流有两种&#xff0c;一是以C为代表的由开发者来决定申请和释放内存&#xff0c;二是以Python为代表的通过语言本身的垃圾回收机制来自动管理内存。Rust开辟了第三种方式&#xff0c;通过所有权系统管理内存。 Rust所…

汇编简介常用语法

为什么要有汇编 因为Cortex-A芯片一上电SP指针还没初始化&#xff0c;C环境还没准备 好&#xff0c;所以肯定不能运行C代码&#xff0c;必须先用汇编语言设置好C环境&#xff0c;比如初始化DDR、设置SP 指针等等&#xff0c;当汇编把C环境设置好了以后才可以运行C代码 GNU语法…

ANR学习

一、ANR 概述 ANR 是 Android 系统用于监控应用是否及时响应的关键机制。形象地说&#xff0c;如同设置定时炸弹场景&#xff1a;系统的中控系统&#xff08;system_server 进程&#xff09;启动倒计时&#xff0c;若应用进程在规定时间内未完成特定任务&#xff0c;中控系统将…

Tcp_socket

Tcp不保证报文完整性&#xff08;面向字节流&#xff09; 所以我们需要在应用层指定协议&#xff0c;确保报文完整性 // {json} -> len\r\n{json}\r\n bool Encode(std::string &message) {if(message.size() 0) return false;std::string package std::to_string(m…