【算法统治世界】动态规划 个人笔记总结

 🎉🎉欢迎光临🎉🎉

🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀

🌟特别推荐给大家我的最新专栏《数据结构与算法:初学者入门指南》📘📘

希望能和大家一起学习!共同进步!

这是苏泽的个人主页可以看到我其他的内容哦👇👇

努力的苏泽icon-default.png?t=N7T8http://suzee.blog.csdn.net

这段时间刷了几十道dp感觉人都要刷傻了 光刷题不行 还是要思考和总结 这篇纯当个人笔记

目录

动态规划的本质

动态规划其实都能归结为有限状态自动机和有向无环图

动态规划如何破局?

使用的条件

如何做?

设计状态

确定状态转移方程

确定初始状态

动态规划的几大类 +例题讲解

1. 背包问题(Knapsack Problem)

例题:0-1背包问题

2. 最长公共子序列(Longest Common Subsequence, LCS)问题

例题:最长公共子序列

3. 最大子序列和问题(Maximum Subarray Problem)

例题:最大子序列和

4. 硬币找零问题(Coin Change Problem)

例题:硬币找零

5. 矩阵链乘法问题(Matrix Chain Multiplication Problem)

例题:矩阵链乘法

坑点

容易忽略“动态”

错在把一开始的那个a[1]就当做了接龙子序列的最长序列             但实则并不一定  或者说  错在没有理解“最少”的含义


动态规划的本质

动态规划其实都能归结为有限状态自动机和有向无环图

动态规划可以被视为一种有限状态自动机,其中每个状态代表了问题的一个子集,状态之间的转移代表了子问题之间的关联。在有向无环图(Directed Acyclic Graph,简称DAG)中,每个节点代表一个状态,而边则代表了状态之间的转移关系。通过这种方式,动态规划将问题转化为在一个DAG上寻找最优路径的问题。

动态规划如何破局?

动态规划的关键在于如何设计状态和状态转移方程,以及如何确定初始状态。以下是动态规划的一般步骤:

使用的条件

在应用动态规划之前,我们需要确保问题满足以下条件:

  1. 最优化原理:问题能够在其子问题的基础上构造出最优解。
  2. 重叠子问题:问题可以被分解为相互重叠的子问题,且子问题的解可以被重复使用。
  3. 有限状态数:状态的数量是有限的,且满足状态数*状态转移数<10^6的条件,以保证算法的可行性。

如何做?

设计状态

设计状态是动态规划中最为关键的一步。状态应该能够唯一地表示问题的某个阶段,同时包含所有必要的信息以决定下一步的行动。状态的设计需要根据具体问题的特点来进行,常见的状态表示方法包括:

  • 位置:在序列问题中,可以用位置来表示状态。
  • 剩余元素:在涉及选择的问题中,可以用剩余可选元素的数量来表示状态。
  • 部分结果:在需要构造结果的问题中,可以用已经得到的部分结果来表示状态。

确定状态转移方程

状态转移方程描述了状态之间的转移关系,它定义了如何从一个或多个状态得到新的状态。状态转移方程的设计需要满足最优化原理,确保能够从子问题的最优解得到原问题的最优解。 常见的状态转移方程类型包括:

  • 相加或相乘:当问题涉及到数值的累加或累乘时。
  • 选择:当问题需要在多个选项中选择一个最优的选项时。
  • 条件转移:当状态转移依赖于某些条件或属性时。

确定初始状态

初始状态是动态规划的起点,它通常代表了问题规模最小的情况下的状态。确定初始状态需要根据问题的具体背景和定义来进行。

动态规划的几大类 +例题讲解

1. 背包问题(Knapsack Problem)

背包问题是一种典型的组合优化问题,通常描述为有一个可以装载重量为W的背包和一组物品,每个物品有自己的重量和价值,目标是选择物品的组合,使得背包中物品的总重量不超过W,且总价值最大。

例题:0-1背包问题

描述:给定n个物品,每个物品有自己的重量w[i]和价值v[i],以及一个最大承重W的背包。求解如何选择物品放入背包,使得背包中物品的总价值最大。

解题思路:定义dp[i][j]为前i个物品中,能够装入容量为j的背包的最大价值。状态转移方程为:

 

dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])

其中,dp[i-1][j]表示不选择第i个物品,而dp[i-1][j-w[i]] + v[i]表示选择第i个物品。

2. 最长公共子序列(Longest Common Subsequence, LCS)问题

LCS问题是一种经典的字符串匹配问题,通常描述为有两个字符串,求解这两个字符串的最长公共子序列的长度。

例题:最长公共子序列

描述:给定两个字符串s1s2,求解它们的最长公共子序列。

解题思路:定义dp[i][j]s1的前i个字符和s2的前j个字符的最长公共子序列的长度。状态转移方程为:

 

if s1[i-1] == s2[j-1] dp[i][j] = dp[i-1][j-1] + 1 else dp[i][j] = max(dp[i-1][j], dp[i][j-1])

其中,相等的情况表示找到了一个公共字符,不相等的情况则取两个方向的最大值。

3. 最大子序列和问题(Maximum Subarray Problem)

最大子序列和问题是一种数组优化问题,通常描述为给定一个整数数组,找到一个连续子数组,使得其和最大。

例题:最大子序列和

描述:给定一个整数数组nums,返回其中最大子序列的和。

解题思路:定义tempSum为当前子数组的和,maxSum为当前找到的最大子序列和。遍历数组,对于每个元素,更新tempSummaxSum

 

if tempSum < 0 tempSum = nums[i] else tempSum += nums[i] if tempSum > maxSum maxSum = tempSum

这种方法的时间复杂度为O(n)。

4. 硬币找零问题(Coin Change Problem)

硬币找零问题是一种货币找零问题,通常描述为给定不同面额的硬币和一个总金额,求解凑成总金额所需的最少硬币个数。

例题:硬币找零

描述:给定不同面额的硬币coins和一个总金额amount,返回凑成总金额所需的最少硬币个数。

解题思路:定义dp[i]为组合成金额i所需的最少硬币个数。状态转移方程为:

 

dp[i] = min(dp[i], dp[i-c] + 1),对于所有c属于coins

其中,dp[i-c] + 1表示使用面额为c的硬币凑成金额i。

5. 矩阵链乘法问题(Matrix Chain Multiplication Problem)

矩阵链乘法问题是一种动态规划在矩阵乘法中的应用问题,通常描述为给定一系列矩阵,求解将它们乘在一起的最小计算成本。

例题:矩阵链乘法

描述:给定一系列矩阵的维度p[1...n],其中p[i]表示第i个矩阵的行数和列数,求解按照哪种顺序乘这些矩阵,使得计算成本最小。

解题思路:定义dp[i][j]为计算矩阵链p[i...j]的最小成本。状态转移方程为:

 

dp[i][j] = min{dp[k][j] + dp[i][k-1] + p[i]*p[k]*p[j]》,对于所有i ≤ k < j

其中,dp[k][j]dp[i][k-1]表示分别计算矩阵链p[i...k]p[k+1...j]的成本,而p[i]*p[k]*p[j]是这两个链相乘时的计算成本。

坑点

容易忽略“动态”

把一个线性的状态作为“固定点” 一直延展 

就像这道 接龙数列:P9242 [蓝桥杯 2023 省 B] 接龙数列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

我一开始的错误

public class MyWrong {public static void main(String[] args) {Scanner in=new Scanner(System.in);int N=in.nextInt();long[] a=new long[N+1];long length =0;for (int i = 1; i <=N ; i++) {a[i]=in.nextInt();length++;}long ans=0;int now=getHead(a[1]);for (int i = 1; i <=N ; i++) {//错在把一开始的那个a[1]就当做了接龙子序列的最长序列// 但实则并不一定  或者说  错在没有理解“最少”的含义if (now==getHead(a[i])){ans++;now=(int)a[i]%10;}}System.out.println(length-ans);}static public int getHead(long l){while (l>=10){l/=10;}return (int)l;}
}

错在把一开始的那个a[1]就当做了接龙子序列的最长序列
             但实则并不一定  或者说  错在没有理解“最少”的含义

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

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

相关文章

面试字节被挂了

分享一个面试字节的经历。 1、面试过程 一面&#xff1a;上来就直接"做个题吧"&#xff0c;做完之后&#xff0c;对着简历上一个项目聊&#xff0c;一直聊到最后&#xff0c;还算比较正常。 二面&#xff1a;做自我介绍&#xff0c;花几分钟聊了一个项目&#xff…

数据库入门-----SQL基础知识

目录 &#x1f4d6;前言&#xff1a; &#x1f4d1;SQL概述&&通用语法&#xff1a; &#x1f433;DDL&#xff1a; &#x1f43b;操作数据库&#xff1a; &#x1f41e;数据类型&#xff1a; &#x1f989;操作表&#xff1a; &#x1f9a6;DML: 语法规则&#x…

浅析安全传输协议HTTPS之“S”

当前互联网&#xff0c;在各大浏览器厂商和CA厂商的推动下&#xff0c;掀起了一股HTTPS应用浪潮。为了让大家更好的了解HTTPS&#xff0c;本文给大家介绍关于HTTPS 中的S一个整体的认识。从其产生的历史背景、设计目标说起&#xff0c;到分析其协议设计结构、交互流程是如何实现…

R语言数据操纵:常用函数

目录 处理循环的函数 lapply函数 apply函数 mapply函数 tapply函数 split函数 排序的函数 sort函数与order函数 总结数据信息的函数 head函数与tail函数 summary函数 str函数 table函数 any函数 all函数 xtab函数 object.size函数 这篇文章主要介绍R语言中处理…

HarmonyOS 开发-一镜到底“页面转场”动画

介绍 本方案做的是页面点击卡片跳转到详情预览的转场动画效果 效果图预览 使用说明 点击首页卡片跳转到详情页&#xff0c;再点击进入路由页面按钮&#xff0c;进入新的路由页面 实现思路 首页使用了一种视觉上看起来像是组件的转场动画&#xff0c;这种转场动画通常是通过…

swiftui macOS实现加载本地html文件

import SwiftUI import WebKitstruct ContentView: View {var body: some View {VStack {Text("测试")HTMLView(htmlFileName: "localfile") // 假设你的本地 HTML 文件名为 index.html.frame(minWidth: 100, minHeight: 100) // 设置 HTMLView 的最小尺寸…

RabbitMQ-延迟队列的使用

目录 一、使用场景 二、第一种方式&#xff1a;创建具有超时功能且绑定死信交换机的消息队列 三、第二种方式&#xff1a;创建通用延时消息 四、第三种方式&#xff1a;使用rabbitmq的延时队列插件&#xff0c;实现同一个队列中有多个不同超时时间的消息&#xff0c;并按时间…

春秋之境28512

题目说该CMS的/single.php路径下&#xff0c;id参数存在一个SQL注入漏洞。访问看一下随便点一个图片。 发现了注入点?id 那么开始查看闭合符一个 就报错了 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for th…

一起学习python——基础篇(10)

前言&#xff0c;Python 是一种面向对象的编程语言。以前大学读书的时候经常开玩笑说的一句话“如果没有对象&#xff0c;就new一个”。起因就是编程老师上课时经常说一句“首先&#xff0c;我们new一个对象”。 今天讲一下python的类和对象。 类是什么&#xff1f;它是一种用…

【linux】基础IO(三)

上一节基础IO我们着重理解了重定向与缓冲区&#xff0c;这节我们需要重点理解文件再磁盘中是怎样存储。以及上一节我们没有涉及到的知识。 stderr到时有什么用&#xff1f; 目录 fd-> 0 1 2&#xff1a;初步理解2怎样将错误与正确输出都打印在一个文件&#xff1f; 文件在硬…

Redis基础操作与持久化

目录 引言 一、Reids工具与数据类型 &#xff08;一&#xff09;Reids工具 &#xff08;二&#xff09;Redis数据类型 1.String&#xff08;字符串&#xff09; 2.Hash&#xff08;哈希&#xff09; 3.List&#xff08;列表&#xff09; 4.Set&#xff08;集合&#xff…

实践笔记-linux内核版本升级(centos7)

linux内核版本升级 1.查看当前内核版本信息2.采用yum方式进行版本升级2.1导入仓库源2.2选择 ML 或 LT 版本安装2.3设置内核启动 3.删除旧版本内核 1.查看当前内核版本信息 #查看操作系统版本 cat /etc/redhat-release #查看系统内核 uname -r2.采用yum方式进行版本升级 2.1导…

白色磨砂质感html5页源码

白色磨砂质感html5页源码&#xff0c;简约的基础上加上了团队成员&#xff0c;自动打字特效音乐播放器存活时间 源码下载 https://www.qqmu.com/2980.html

vscode的源码插件GitHub Repositories

打铁还需自身硬&#xff0c;需要不断提升自我&#xff0c;提升自我的一种方式就是看源码&#xff0c;站在更高的维度去理解底层原理&#xff0c;以便以后更好的开发和解决问题&#xff0c;由于源码一个动不动就是几个G甚至十几个G&#xff0c;如果一个个源码下载下来&#xff0…

数字图像处理项目——基于BCNN和迁移学习的鸟类图像细粒度分类(论文/代码)

完整的论文代码见文章末尾 以下为核心内容 摘要 本文采用了ResNet50、VGG19、InceptionV3和Xception等四种不同的深度神经网络模型&#xff0c;并应用于鸟类图像的细粒度分类问题中&#xff0c;以探究其在该任务上的性能表现。 其中&#xff0c;本文使用了BCNN&#xff08;B…

查分约束学习

问题模型&#xff1a; 有n个变量&#xff1a;&#xff0c;有m个约束条件 令差分数组&#xff0c;可以知道如果x1x2<q&#xff0c;那么与j和i-1有关联 由画图可知&#xff0c;如果有在i-1至j建立的有向图中跑最短路&#xff0c;那么dis[n]即为最小的约束变量 另外&#x…

Chrome浏览器如何跟踪新开标签的网络请求?

在测试一个东西的时候&#xff0c;它虽然是a链接&#xff0c;但是&#xff0c;是由前端在js里写跳转的。我又必须要知道它的跳转链接&#xff0c;只能用截屏的方式来捕捉浏览器的地址栏链接 打开浏览器控制台(F12)点击红色箭头打钩为弹出式窗口自动打开DevTools 英文版调试参…

华大单片机新建工程步骤

1.新建文件夹&#xff0c;比如00_LED 2.拷贝 hc32f460_ddl_Rev2.2.0\driver 到 00_LED 3.拷贝 hc32f460_ddl_Rev2.2.0\mcu\common 到 00_LED 4.拷贝 hc32f460_ddl_Rev2.2.0\example\ev_hc32f460_lqfp100_v2\gpio\gpio_output\source 到 00_LED 5.拷贝 hc32f460_ddl_Rev2.2.…

933.最近的请求次数

题目&#xff1a;写一个 RecentCounter 类来计算特定时间范围内最近的请求。 请你实现 RecentCounter 类&#xff1a; RecentCounter() 初始化计数器&#xff0c;请求数为 0 。int ping(int t) 在时间 t 添加一个新请求&#xff0c;其中 t 表示以毫秒为单位的某个时间&#x…

HarmonyOS 开发-使用SideBarContainer侧边栏淡入淡出动效实现案例

介绍 在2in1或平板上&#xff0c;群聊侧边栏是一种较为常用的功能&#xff0c;虽然HarmonyOS已经具备了基本的动效&#xff0c;但是部分情况下开发者可能有定制侧边栏动效的需求&#xff0c;本例主要介绍了如何基于显式动画实现侧边栏的淡入淡出动效。 效果图预览 使用说明&a…