动态规划——区间dp [石子合并]

news2024/10/6 22:19:53

动态规划——区间dp

  • 什么是动态规划
    • 区间dp
      • 定义
      • 应用
  • 例题引入
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例
      • 样例输入
      • 样例输出
    • 提示
  • 贪心法
  • 区间dp
    • 优缺点:
    • AC代码:
    • 代码详解
      • 三层for循环
      • 状态转移方程
      • 环形的处理

在这里插入图片描述

什么是动态规划

动态规划(dp)是一种通过将问题分解为子问题,并利用已解决的子问题的解来求解原问题的方法。适用于具有重叠子问题和最优子结构性质的优化问题。通过定义状态和状态转移方程,动态规划可以在避免重复计算的同时找到问题的最优解,是一种高效的求解方法,常用于解决各种问题,如最短路径、背包问题、序列比对等。


区间dp

在这里插入图片描述

定义

区间dp是一种dp的应用,用于解决涉及区间的问题。
它将问题划分为若干个子区间,并通过定义状态和状态转移方程来求解每个子区间的最优解,最终得到整个区间的最优解。


应用

区间动态规划常用于解决一些涉及区间操作的问题,如最长公共子序列、最长回文子串等。在区间动态规划中,通常需要定义一个二维数组来表示子区间的状态,并通过填表的方式逐步求解子区间的最优解,最后得到整个区间的最优解。区间动态规划是一种高效的求解方法,可以有效地解决各种区间问题。



例题引入

石子合并是一道非常经典的区间DP的例题,很适合新手练习,下面我们看看这个题目:

题目描述

在一个圆形操场的四周摆放 N N N 堆石子,现要将石子有次序地合并成一堆,规定每次只能选相邻的 2 2 2 堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。

试设计出一个算法,计算出将 N N N 堆石子合并成 1 1 1 堆的最小得分和最大得分。

输入格式

数据的第 1 1 1 行是正整数 N N N,表示有 N N N 堆石子。

2 2 2 行有 N N N 个整数,第 i i i 个整数 a i a_i ai 表示第 i i i 堆石子的个数。

输出格式

输出共 2 2 2 行,第 1 1 1 行为最小得分,第 2 2 2 行为最大得分。

样例

样例输入

4
4 5 9 4

样例输出

43
54

提示

1 ≤ N ≤ 100 1\leq N\leq 100 1N100 0 ≤ a i ≤ 20 0\leq a_i\leq 20 0ai20



贪心法

稍微想想就知道不可行,因为它每次只能合并相邻的两堆石子,用贪心的话会答案错误,因此我们考虑区间dp。


区间dp

利用区间动态规划来解决此类问题。

优缺点:

优点缺点
可以求出正解时间复杂度高
代码量相对较少效率低
容易理解数据量大会超时
*** Sirius 你这缺点不都是同一个吗? 不不不,这不一样。 沉思了一小会 ??? *** Sirius

确实,此题的时间复杂度高达 O ( 2 n 3 ) O(2n^3) O(2n3),若非这道题的数据量极小,下面的代码便会超时,那么就需要用一个特殊方法来优化一下。

AC代码:

#include <bits/stdc++.h>
using namespace std;
int n,ans1=0x7fffffff,ans2,a[300],sum[300];
int mi[300][300],ma[300][300];
int main() {
	cin >>n;
	for (int i=1; i<=n; i++) {
		cin >>a[i];
		a[i+n]=a[i];
	}
	for (int i=1; i<=2*n; i++)
		sum[i]=sum[i-1]+a[i];
	memset(mi,0x3f,sizeof(mi));
	for (int i=1; i<=2*n; i++)
		mi[i][i]=0;
	for (int l=1; l<n; l++) {
		for (int i=1; i+l<=2*n; i++) {
			for (int k=i; k<i+l; k++) {
				mi[i][i+l]=min(mi[i][i+l],mi[i][k]+mi[k+1][i+l]+sum[i+l]-sum[i-1]);
				ma[i][i+l]=max(ma[i][i+l],ma[i][k]+ma[k+1][i+l]+sum[i+l]-sum[i-1]);
			}
		}
	}
	for (int i=1; i<n; i++)
		ans1=min(ans1,mi[i][i+n-1]);
	for (int i=1; i<n; i++)
		ans2=max(ans2,ma[i][i+n-1]);
	cout <<ans1 <<endl <<ans2;
	return 0;
}

代码详解

三层for循环

  • 第一层for循环用来分区间,我们可以选择将一个大区间分成若干个小区间,那么分的标准是什么呢?这就是第一层for循环的作用, l e n len len就是每次分的区间长度。
  • 第二层循环就是定义区间的左端点, l = 1 l=1 l=1,再根据 l e n = 2 len=2 len=2,就能确定区间为 ( 1 , 2 ) (1,2) (1,2),即 f [ 1 ] [ 2 ] f[1][2] f[1][2]
  • 然后第三层循环就是拆分了,如上图, l e n = 2 len=2 len=2的时候是无法拆分了,但是 l e n = 3 len=3 len=3的时候是可以拆成 f [ 1 ] [ 2 ] , f [ 3 ] [ 3 ] , f [ 1 ] [ 1 ] , f [ 2 ] [ 3 ] f[1][2],f[3][3],f[1][1],f[2][3] f[1][2],f[3][3],f[1][1],f[2][3],以及各个数据都有或没有拆分方法。

状态转移方程

区间拆分了,那么我们如何去算转移方程呢?我们将两个区间 ( 1 , 2 ) (1,2) (1,2) ( 3 , 4 ) (3,4) (3,4)进行合并,那么就是1,2的代价加上3,4的代价,再加上1到4的区间和,具体的式子如下

f[1][4] = min(f[1][4],f[1][2]+f[3][4]+s[4]-s[0]);

为什么这么计算呢,因为你要知道你在求解的过程中是通过小的区间组合成较大的区间的,而你所用到的这两个小的区间 f [ 1 ] [ 2 ] + f [ 3 ] [ 4 ] f[1][2]+f[3][4] f[1][2]+f[3][4],已经得出了最优解了,那么得出最优解需不需要花费代价呢?当然需要,所以我们需要加上那段花费,那么简单来说就是

f[1][2]+f[3][4]=s[2]-s[0]+s[4]-s[2]

因此,状态转移方程便有了:

f[i][i+l]=min(f[i][i+l],f[i][k]+f[k+1][i+l]+s[i+l]-s[i-1]);

环形的处理

我们仔细阅读题目即可发现:石子是按照环形摆放的,因此区间的头和尾是能够合并的,那么如何处理呢?
方法很简单,只需要将整一条线性的石头复制一个,让第二个的头对着第一个的尾,然后正常处理即可。
这一点在程序的很多地方可以体现出来,如:

	for (int i=1; i<=n; i++) {
		cin >>a[i];
		a[i+n]=a[i];
	}

	for (int i=1; i<=2*n; i++)

以及

	for (int i=1; i+l<=2*n; i++)

等等。

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

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

相关文章

高数基础10不定积分

目录 不定积分 原函数存在定理&#xff1a; 定理1 定理2&#xff1a; 例题1&#xff1a; 例题2&#xff1a; 例题3&#xff1a; 不定积分的性质&#xff1a; 不定积分的基本公式&#xff1a; 例题4&#xff1a; 例题5&#xff1a; ​编辑 例题6&#xff1a; 三种主要积分法…

喜讯!安全狗再次获得“纳税大户”称号

近日&#xff0c;厦门市思明区人民政府公布了《2022年度纳税大户名单》。安全狗入选名单并被授予“2022年度纳税大户”称号。 厦门服云信息科技有限公司&#xff08;品牌名&#xff1a;安全狗&#xff09;成立于2013年&#xff0c;致力于提供云安全、&#xff08;云&#xff09…

入门_科研论文写作

不整理笔记&#xff0c;等于没学过&#xff08;for me&#x1f643;&#xff09; Ideas 多读论文动手做实验 找对应的、最新的数据集&#xff08;比如某一类的效果欠佳&#xff0c;那是为什么捏&#xff09; 从论文的实验分析得出结论 跑别人的代码&#xff0c;分析预测的数据…

LNMP架构及应用部署

LNMP架构及应用部署 安装nginx 关闭防火墙和selinux [rootlocalhost ~]#systemctl stop firewalld [rootlocalhost ~]# setenforce 0 [rootlocalhost ~]# iptables -F 安装依赖软件 [rootlocalhost ~]# mount /dev/cdrom /mnt ---挂载光盘&#xff08;先要创建yum仓…

SQL-每日一题【511.游戏玩法分析Ⅰ】

题目 活动表 Activity&#xff1a; 写一条 SQL 查询语句获取每位玩家 第一次登陆平台的日期。 查询结果的格式如下所示&#xff1a; 解题思路 前置知识 MIN&#xff08;&#xff09;函数 MIN 函数返回一列中的最小值。NULL 值不包括在计算中。 SQL MIN() 语法 SELECT MIN(co…

2023WAIC世界人工智能大会

“在卢浮宫看蒙娜丽莎的感觉” 图源自朋友 附言&#xff1a; 前几天在想能不能为AI文本生成设计一种AI独有的字体&#xff0c;结果今天看到这个新闻&#xff1a;阿里巴巴全新可变字体发布&#xff0c;免费可商用。

Java微服务金融项目智牛股-基础知识三(Restful、HATEOAS、GRPC、SEATA )

Restful定义 Restful是一种软件架构与设计风格&#xff0c; 并非一套标准&#xff0c; 只提供了一些原则与约定条件。REST提供了一组架构约束&#xff0c;当作为一个整体来应⽤用时&#xff0c;强调组件交互的可伸缩性。接⼝口的通⽤用性、组件的独⽴立部署、以及⽤用来减少交…

SSMP整合案例(13) 在界面中实现编辑操作

做完我们的删除 那肯定是做编辑 其实编辑和添加基本是一个东西 我们打开 src下的 components 下的bookFillIn.vue 组件 之前我们做添加的这个弹窗组件 加一个函数叫 editBook 接收一个参数 id 内容先不管 然后 在data中 加多一个键 id 值 null 然后 将sensor 展开弹窗函数 更…

C# PaddleInference 文字检测(只检测不识别)

效果 项目 Demo下载 代码 using OpenCvSharp.Extensions; using OpenCvSharp; using Sdcb.PaddleInference.Native; using Sdcb.PaddleInference; using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Linq; using Syst…

【完整代码】电商购物系统Python,基于Flask框架实现

一、介绍 电商购物系统Python&#xff0c;基于Flask框架实现。 实现用户查看商品、购买商品、添加购物车、商城订单、编辑个人信息、点击喜欢不喜欢等、商品评论、登录注册、查看物流信息等功能。 实现商家发布商品、查看销售列表、管理商品、物流信息更新、个人信息修改等功能…

腾讯游戏服务器外包二面

1.基础问题 2.网络协议 3.数据结构 3.1二叉树的前序遍历 3.2实现二叉树的前序遍历 https://www.nowcoder.com/practice/5e2135f4d2b14eb8a5b06fab4c938635?tpId295&tqId2291302&ru/exam/oj&qru/ta/format-top101/question-ranking&sourceUrl%2Fexam%2Foj…

如何查找电脑蓝屏原因之详解

一、电脑蓝屏存储位置 电脑蓝屏日志是一种非常常见的错误提示&#xff0c;它经常发生在Windows操作系统中。当Windows系统遇到无法处理的错误时&#xff0c;会自动将错误信息记录在蓝屏日志文件中。这些日志文件通常存储在C盘的目录下windows文件中的Minidump文件夹中。 以dmp格…

Openlayers实战:绘制矩形,正方形,正六边形

Openlayers地图中,绘制图形是非常重要的一个功能。Openlayers主要使用draw类来绘制图形,在实际项目中有时候会绘制矩形和正多边形。 下面的示例是绘制矩形,正方形,正多边形。 效果图 源代码 /* * @Author: 大剑师兰特(xiaozhuanlan),还是大剑师兰特(CSDN) * @此源代…

基于Python爬虫+KNN数字验证码识别系统——机器学习算法应用(含全部工程源码)+训练数据集

目录 前言总体设计系统整体结构图系统流程图 运行环境Python 环境 模块实现1. 数据爬取2. 去噪与分割3. 模型训练及保存4. 准确率验证 系统测试工程源代码下载其它资料下载 前言 本项目利用Python爬虫技术&#xff0c;通过网络爬取验证码图片&#xff0c;并通过一系列的处理步…

QT5项目程序打包成可执行exe程序(绿色版)

一、QT在release模式下编译生成.exe 二、然后新建一个空白文件夹package&#xff0c;再将在release模式下生成的.exe文件复制到新建的文件夹中package。 三、打开QT5的命令行&#xff08;选择项目所使用的的环境&#xff09; 查找项目使用环境 打开命令行 四、在命令行输入命令…

马斯克:未来会涌现大量机器人,与人类比例有望超过1比1

在世界人工智能大会上&#xff0c;特斯拉的马斯克通过网络发表了视频演讲&#xff0c;涵盖了特斯拉人形机器人Optimus、自动驾驶和人工智能等话题。他赞扬了中国的AI产业&#xff0c;并表示中国在决心和实施方面非常出色&#xff0c;包括AI产业发展在内。 特斯拉的人型机器人目…

数学美学:探索“既不是最小值也不是最大值”的魅力

本篇博客会讲解力扣“2733. 既不是最小值也不是最大值”的解题思路&#xff0c;这是题目链接。 本题的思路是&#xff1a; 若数组只有2个元素&#xff0c;显然任意一个元素不是最小值就是最大值。若数组有3个以上的元素&#xff0c;由于提示中的第3点&#xff1a;数组中的所有…

中国首家外资独资期货公司,摩根大通期货持仓龙虎榜的持仓动向和盈亏状况

摩根大通期货&#xff0c;为什么持仓量长期排在期货龙虎榜前列 摩根大通是一家全球领先的金融服务机构&#xff0c;拥有超过200年的历史&#xff0c;业务遍及全球100多个国家和地区。这个期货公司比较神秘&#xff0c;只有上海一个营业部&#xff0c;在业务方向上以机构客户为服…

YOLOv5、YOLOv8改进教程:7. 添加SK-Net注意力机制

论文地址:Selective Kernel NetworksGithub:https://github.com/implus/SKNet如果你是深度学习小白,阅读本文前建议先学习一下 📖《新手入门深度学习》如果你有一定基础,但是缺乏实战经验,可通过 📖《深度学习100例》 补齐基础另外,我们正在通过 🔥365天深度学习训…

ATM模拟-管理员登录用户查询

项目来源&#xff1a;新星计划2023【JavaWeb实现ATM机存取款项目实战】 学习方向报名入口-CSDN社区 目录 管理员登录 管理员登录逻辑 管理员登录主程序 功能实现 代码如下&#xff1a; 用户信息封装 实现功能 代码实现&#xff1a; 业务层代码具体实现 功能实现 业…