区间dp-

间dp就是在区间上进行动态规划,求解一段区间上的最优解。主要是通过合并小区间的最优解进而得出整个大区间上最优解的 dp 算法。

既然让我求解在一个区间上的最优解,那么我把这个区间分割成一个个小区间,求解每个小区间的最优解,再合并小区间得到大区间即可。 

所以在代码实现上,我可以枚举区间长度len为每次分割成的小区间长度(由短到长不断合并),内层枚举该长度下可以的起点,自然终点也就明了了。然后在这个起点终点之间枚举分割点,求解这段小区间在某个分割点下的最优解。

可能性展开的常见方式:

1.基于两侧端点讨论的可能性展开

2.基于范围上划分点的可能性展开

基于两侧端点讨论的可能性题目

题目一

暴力解法:

直接采用递归的方法,对两侧端点进行讨论,取min

int cmp(char* s, int r, int l)
{
	if (r == l) //如果只有一个字符
		return 0;
	if (r + 1 == l) //如果只有两个字符
	{
		if (s[r] == s[l])
			return 0;
		else 
			return 1;
	}
	if (s[r] == s[l]) // 如果两个端点的字符相同
		return cmp(s, l+1, r-1);
	else
		return min(cmp(s, l+1, r)+1, cmp(s, l, r-1)+1);
}

当两个端点的字符不相同时,例如aab,我们有两种方式进行插入,我们先满足 l 位置与后面的位置相同,也就是在 b 的后面插入 a 时,那下一步的 r 保持不变,l + 1,当我们也可以满足 r 位置与前面的位置相同,也就是在 a 的前面插入 b 时,则下一步的 l 保持不变,r - 1

两个操作都加一,取最小值。

暴力的递归的方法递归层数太多,那我们就可以通过记忆化搜索

优化一

int f2(char* s, int l, int r, int (*dp)[10])
{
	if (dp[l][r] != -1)
		return dp[l][r]
	int ans;
	if (l == r)
	{
		ans = 0;
	}
	else if (l + 1 == r)
	{
		if (s[l] = s[r])
		{
			ans = 0;
		}
		else
		{
			ans = 1;
		}
	}
	else
	{
		if (s[l] == s[r])
			ans = f2(s, l+1, r-1, dp);
		else
			ans = min(f2(s, l+1, r, dp), f2(s, l, r-1, dp)) + 1;
	}
	dp[l][r] = ans;
	return ans;
}

也可以分析其严格依赖位置的动态规划

(分析可变参数的范围)

假设这个字符串长度为 5

那么我们就可以做出它的二维dp表(dp[i][j] 表示从 i 到 j 保持回文的最小操作次数)

因为 l 一定小于 r

所以它的表为:

当l == r的时候,操作次数一定为0

当l + 1 == r时

我们也可以直接求出对应的dp值

最终,我们要求的就是最右上角的格子(也就是dp[4][4])

那我们分析dp[i][j] 的位置依赖

从递归可知:

dp[i][j] 是由 dp[i+1][j-1],dp[i+1][j],dp[i][j-1] 三个位置得到

因此我们可以发现要求出dp[ i ][ j ]就必须先求出dp[ i+1 ][ j-1 ],dp[ i+1 ][ j ],dp[ i ][ j-1 ]

所以我们的求解顺序:

所以我们就可以直接求出dp表

# include <stdio.h>



int main()
{
	char s[10];
	int dp[10][10]; //表示从i到j位置保持回文的最少操作次数 
	int n = 10; //字符串长度 
	for (int i=0; i<n-1; ++i)
	{
		if (s[i] == s[i+1])
			dp[i][i+1] = 0;
		else
			dp[i][i+1] = 1;
	}
	for (int l=n-3; l>=0; --l) //从小到上 
		for (int r = l+2; r<n; ++r) //从左到右
		{
			if (s[l] == s[r])
				dp[l][r] = dp[l+1][r-1];
			else
				dp[l][r] = min(dp[l][r-1], dp[l+1][r]);
		}
		
}

也可以用一维dp优化空间

代码类似

题目二

暴力递归:

# include <stdio.h>

//考虑num[l …r]范围上的数字进行游戏,轮到玩家1
//返回玩家1最终能获得多少分数,玩家1和玩家2都绝顶聪明 
int cmp(int* num, int l, int r)
{
	if (l == r)
		return num[l];
	if (l + 1 == r )
		return max(num[l], num[r]);
	
	//当玩家1,拿num[l]后,轮到玩家2了,他考虑num[l+1, r],因为两个人都是 
	//顶聪明,所以玩家2一定拿max(num[l+1], num[r]),然后轮到玩家1面对的情况
	//一定是 min(cmp(num, l+2, r), cmp(num, l+1, r-1))
	int p1 = num[l] + min(cmp(num, l+2, r), cmp(num, l+1, r-1));
	//当玩家1,拿num[r]后 … 
	int p2 = num[r] + min(cmp(num, l+1, r-1), cmp(num, l, r-2));
	return max(p1, p2);
}

int main()
{
	int sum = 0;
	int num[10];
	for (int i=0; i<10; ++i)
	{
		scanf("%d", &num[i]);
		sum = sum + num[i];
	}
	int n = 10;
	int first = cmp(num, 0, n-1); //玩家1 
	int second = sum - first; //玩家2 
	
 } 

记忆化搜索

# include <stdio.h>
int dp[10][10]; 
//考虑num[l …r]范围上的数字进行游戏,轮到玩家1
//返回玩家1最终能获得多少分数,玩家1和玩家2都绝顶聪明 
int cmp(int* num, int l, int r)
{
	int ans;
	if (dp[l][r] != -1)
		return dp[l][r];
	if (l + 1 == r )
		ans = max(num[l], num[r]);
	
	else
	{
		int p1 = num[l] + min(cmp(num, l+2, r), cmp(num, l+1, r-1));
		int p2 = num[r] + min(cmp(num, l+1, r-1), cmp(num, l, r-2));
		ans = max(p1, p2);
	}
	return ans;
}

int main()
{
	memset(dp, -1, sizeof(dp));
	int sum = 0;
	int num[10];
	for (int i=0; i<10; ++i)
	{
		scanf("%d", &num[i]);
		sum = sum + num[i];
	}
	int n = 10;
	int first = cmp(num, 0, n-1); //玩家1 
	int second = sum - first; //玩家2 
	
 } 

也可以分析其严格依赖位置的动态规划

(分析可变参数的范围)

dp[i][j] 是由 dp[i + 2][j], dp[l+1][r - 1], dp[l][r-2]得到

代码于上题类似

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在 Rust 中实现 TCP : 3. TCP连接四元组

连接四元组 我们的项目已经取得了很大的进展——接下来能够开始解决 TCP 协议的实现问题。下面将讨论 TCP 的一些行为及其各种状态。 在多任务操作系统中&#xff0c;各种应用程序&#xff08;例如 Web 服务器、电子邮件客户端等&#xff09;需要同时进行网络访问。为了区分这…

openGauss学习笔记-236 openGauss性能调优-SQL调优-Query执行流程

文章目录 openGauss学习笔记-236 openGauss性能调优-SQL调优-Query执行流程236.1 Query执行流程236.1.1 调优手段之统计信息236.1.2 调优手段之GUC参数236.1.3 调优手段之底层存储236.1.4 调优手段之SQL重写 openGauss学习笔记-236 openGauss性能调优-SQL调优-Query执行流程 S…

如何选择程序员职业赛道

目录 前言1 个人技能分析1.1 技术栈评估1.2 经验积累1.3 数据科学能力 2 兴趣与价值观2.1 用户交互与界面设计2.2 复杂问题解决与系统优化 3 长期目标规划4 市场需求分析4.1 人工智能和云计算4.2 前沿技术趋势 5 就业前景5.1 前端在创意性公司中的应用5.2 后端在大型企业中的广…

全面分析vcruntime140_1.dll无法继续执行代码的处理方法,3分钟修复vcruntime140_1.dll

如果系统弹出一个错误警告&#xff0c;指出“vcruntime140_1.dll无法继续执行代码”&#xff0c;这通常意味着您的Windows系统中缺失了一个关键的文件&#xff0c;或者该文件已损坏。​vcruntime140_1.dll​是随Visual C Redistributable for Visual Studio 2015, 2017和2019提…

【更新2022】各省数字经济水平测算 原始数据+结果 2011-2022

数据说明&#xff1a;参照赵涛等&#xff08;2020&#xff09;的文章&#xff0c;利用熵值法和主成分对省市数字经济水平进行测算&#xff0c;原始数据来自第五期北大数字普惠金融指数&#xff0c;含原始数据&#xff0c;以及熵值法、主成分两种测算结果。一、数据介绍 数据名…

无人机/飞控--ArduPilot、PX4学习历程记录(1)

本篇博客用来记录个人学习记录&#xff0c;存放各种文章链接、视频链接、学习历程、实验过程和结果等等.... 最近在整无人机项目&#xff0c;接触一下从来没有接触过的飞控...(听着就头晕)&#xff0c;本人纯小白。 目录 PX4、Pixhawk、APM、ArduPilot、Dronecode Dronekit…

Linux 设置快捷命令

以ll命令为例&#xff1a; 在 Linux 系统上&#xff0c;ll 命令通常不是一个独立的程序&#xff0c;而是 ls 命令的一个别名。 这个别名通常在用户的 shell 配置文件中定义&#xff0c;比如 .bashrc 或 .bash_aliases 文件中。 要在 Debian 上启用 ll 命令&#xff0c;你可以按…

鸿蒙 Stage模型-AbilityStage、Context、Want

前提&#xff1a;基于官网3.1/4.0文档。参考官网文档 基于Android开发体系来进行比较和思考。&#xff08;或有偏颇&#xff0c;自行斟酌&#xff09; 一、 AbilityStage 1.概念 AbilityStage是一个Module级别的组件容器&#xff0c;应用的HAP在首次加载时会创建一个AbilitySt…

怎么写苹果群控核心功能的源代码!

随着移动设备的普及和技术的不断发展&#xff0c;苹果设备群控技术成为了许多开发者关注的焦点&#xff0c;苹果群控技术允许开发者通过编写源代码&#xff0c;实现对多台苹果设备的集中管理和控制。 一、了解苹果群控技术的基本原理 在编写苹果群控核心功能的源代码之前&…

书生浦语全链路开源体系

推荐阅读论文 A Survey Of Large Language Models 书生浦语开源的模型 从模型到应用 书生浦语开源体系 书生万卷开源数据集 除此之外还有OpenDataLab国内数据集下载网站。 预训练框架InterLM-Train 微调框架XTuner 评测工具体系 国内外常见的大语言模型评测基准&#xff1a…

YOLOv8独家原创改进:特征融合涨点篇 | 广义高效层聚合网络(GELAN) | YOLOv9

💡💡💡本文独家改进:即结合用梯度路径规划(CSPNet)和(ELAN)设计了一种广义的高效层聚合网络(GELAN),高效结合YOLOv8,实现涨点。 将GELAN添加在backbone和head处,提供多个yaml改进方法 💡💡💡在多个私有数据集和公开数据集VisDrone2019、PASCAL VOC实现…

基于华为atlas的unet分割模型探索

Unet模型使用官方基于kaggle Carvana Image Masking Challenge数据集训练的模型。 模型输入为572*572*3&#xff0c;输出为572*572*2。分割目标分别为&#xff0c;0&#xff1a;背景&#xff0c;1&#xff1a;汽车。 Pytorch的pth模型转化onnx模型&#xff1a; import torchf…

bun 单元测试

bun test Bun 附带了一个快速、内置、兼容 Jest 的测试运行程序。测试使用 Bun 运行时执行&#xff0c;并支持以下功能。 TypeScript 和 JSX生命周期 hooks快照测试UI 和 DOM 测试使用 --watch 的监视模式使用 --preload 预加载脚本 Bun 旨在与 Jest 兼容&#xff0c;但并非所…

北京Excel表格线下培训班

Excel培训目标 熟练掌握职场中Excel所需的公式函数计算&#xff0c;数据处理分析&#xff0c;各种商务图表制作、动态仪表盘的制作、熟练使用Excel进行数据分析&#xff0c;处理&#xff0c;从复杂的数据表中把数据进行提取汇总 Excel培训形式 线下面授5人以内小班&#xff…

分享Web.dev.cn中国开发者可以正常访问

谷歌开发者很高兴地宣布&#xff0c;web.dev 和 Chrome for Developers 现在都可以通过 .cn 域名访问&#xff0c;这将帮助中国的开发者更加容易获取我们的内容。 在 .cn 域名上&#xff0c;我们已向您提供所有镜像后的内容&#xff0c;并提供支持的语言版本。 Web.dev 中国开…

uipath调用js代码

1&#xff0c;调用js代码&#xff0c;不带参数&#xff0c;没有返回值 为了去掉按钮的disabled属性 function(){ document.getElementsByClassName(submitBtn)[0].removeAttribute(disabled); } 2&#xff0c;调用js代码&#xff0c;带参数&#xff0c;没有返回值 输入参数&a…

el-dialog封装组件

父页面 <template><div><el-button type"primary" click"visible true">展示弹窗</el-button><!-- 弹窗组件 --><PlayVideo v-if"visible" :visible.syncvisible /></div> </template><sc…

Python-Numpy-计算向量间的欧式距离

两个向量间的欧式距离公式&#xff1a; a np.array([[2, 2], [4, 5], [6, 7]]) b np.array([[1, 1]]) # 使用L2范数计算 dev1 np.linalg.norm(a - b, ord2, axis1) # 使用公式计算 dev2 np.sqrt(np.sum((a - b) ** 2, axis1)) print(dev1.reshape((-1, 1)), dev2.reshape((…

掌握WhatsApp手机号质量评分:增加信息可达性

WhatsApp手机号质量评分是用于衡量用户手机号与平台互动的健康度&#xff0c;确保用户通讯时的合规性和安全性。在实掌握WhatsApp手机号质量评分实际应用中&#xff0c;这个评分会影响用户的消息发送的可达性。高质量的评分意味着用户的账户被视为可信赖的&#xff0c;其发送的…

2024最新ChatGPT网站源码, AI绘画系统

一、前言说明 R5Ai创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GP…