【DP动态规划】学习笔记大全

news2024/11/15 17:16:57

-------------------------------------------------------本篇文章尚未完结,大家可以先看已有部分-------------------------------------------------------


在这里插入图片描述

【DP动态规划】学习笔记大全

  • Part 1 背包DP
    • 1.1 01背包
      • 1.1.1 题意解释
      • 1.1.2 为什么不使用贪心
      • 1.1.3 该如何进行 01DP
      • 1.1.4 推荐例题
      • 1.1.5 优化方式
    • 1.2完全背包
      • 1.2.1 题意解释
      • 1.2.2 如何进行状态转移
      • 1.2.3 推荐例题
  • Part 2 区间DP
    • 2.1典例引入
    • 2.2 基本概念
    • 2.3 例题分析
      • 2.3.1 题意解释
      • 2.3.2 环的处理
      • 2.3.3 题目思路
      • 2.3.4 主要代码
      • 2.4 推荐例题

Part 1 背包DP

1.1 01背包

1.1.1 题意解释

你有一个容量为 n n n 的背包,一共有 m m m 种物品,每个物品都有一个权值 v i v_i vi 和体积 w i w_i wi,在不超过背包容量的前提下,尽可能装权值最多的东西

1.1.2 为什么不使用贪心

考虑到本题,没学过DP的人可能会用以下两种贪心:

  1. 装权值越大的东西:(错误)
i i i123
v i v_i vi432
w i w_i wi70691

对于上面这一组数据,当 n = 70 n = 70 n=70 时如果我们使用这样的贪心策略,会优先选择体积为 70 70 70,权值为 4 4 4 的物品,但明显的,选择另外两个会更优。

  1. 计算平均值,在许可范围内选择平均值最大的
i i i123
v i v_i vi150100100
w i w_i wi1007574
v i w i \frac{v_i}{w_i} wivi 3 2 \frac{3}{2} 23 4 3 \frac{4}{3} 34 50 37 \frac{50}{37} 3750

明显的,对于上述样例,这种方法依然得不到正确答案。

1.1.3 该如何进行 01DP

我们设 d p i , j dp_{i,j} dpi,j 表示当前取到了第 i i i 个物品, 还剩 j j j 点容量时的最大值,那么我们即可得到一个转移方程:

d p i , j = m a x ( d p i − 1 , j − w i + v i , d p i − 1 , j ) ; dp_{i,j} = max(dp_{i - 1,j - w_i}+v_i,dp_{i - 1,j}); dpi,j=max(dpi1,jwi+vi,dpi1,j);

换一句话说,这就表示“把第 i i i 个,第 i + 1 i+1 i+1个,…, n n n个物品装到容量为 j j j 的背包中的最大权值”。

那么我们根据以上转移方程就可以得到以下代码:

 for(int i=1;i<=m;i++) {
        for(int j=t;j>=0;j--)  {
            if(j>=w[i])
                dp[i][j]=max(dp[i-1][j-w[i]]+val[i],dp[i-1][j]); 
            else
                dp[i][j]=dp[i-1][j];           
        }
 }

明显的,答案就是 d p m , n dp_{m,n} dpm,n

1.1.4 推荐例题

P1048 [NOIP2005 普及组] 采药
P1049 [NOIP2001 普及组] 装箱问题
P2871 [USACO07DEC] Charm Bracelet S
P1060 [NOIP2006 普及组] 开心的金明
P1164 小A点菜

1.1.5 优化方式

对于 01背包,因为 DP 的无后效性,所以我们可以考虑用滚动数组进行优化,那么这个转移方程就变成了:

f j = m a x ( f j , f j − v i + w i ) f_j = max(f_j,f_j−v_i+w_i) fj=max(fj,fjvi+wi)

这样就可以省下大幅的空间。
注意:使用滚动数组时要倒序遍历


1.2完全背包

1.2.1 题意解释

  • 完全背包与 01背包类似,只不过每个物品可以选择无限多次。

1.2.2 如何进行状态转移

因此我们考虑任然使用 01 背包的状态设计,但明显的是,01背包的状态转移已经不适用于完全背包。
我们发现,对于 d p i , j dp_{i,j} dpi,j,只要从 d p i , j − w i dp_{i,j - w_i} dpi,jwi转移即可,这样满足了DP的无后效性,那么我们可以得到以下的状态转移公式:

d p i , j = m a x ( d p i − 1 , j − w i + v i , d p i − 1 , j ) ; dp_{i,j} = max(dp_{i - 1,j - w_i}+v_i,dp_{i - 1,j}); dpi,j=max(dpi1,jwi+vi,dpi1,j);

同样的,完全背包也可以像 01背包一样压缩掉一维,优化空间复杂度,同时,在压缩之后的转移顺序为正序,由此我们可以得到以下代码:

 for (int i = 1; i <= n; i++)
    for (int l = w[i]; l <= m; l++)
      if (f[l - w[i]] + v[i] > f[l]) f[l] = f[l - w[i]] + v[i];

1.2.3 推荐例题

P1616 疯狂的采药
P2722 [USACO3.1] 总分 Score Inflation
P1679 神奇的四次方数
P1832 A+B Problem(再升级)

Part 2 区间DP

2.1典例引入

  • 给定长度为 n n n 的序列 a a a,每次可以将其中连续的一段回文子段删去,删去后左右两段将合并,问最少用几次操作可以消除整个区间
  1. 经观察发现,每个时刻消去的位置总是一个连续的区间。
  2. 因此我们考虑消去区间 [ i , j ] [i,j] [i,j] 时:
  • a i a_i ai a j a_j aj 不在一起消去,那我们总是可以找到一个分界点 k k k ,使得区间 [ i , k ] [i,k] [i,k] 和区间 [ k + 1 , j ] [k + 1,j] [k+1,j] 可以分别消去。
  • a i a_i ai a j a_j aj,那他们只需要接在 [ i + 1 , j − 1 ] [i + 1,j - 1] [i+1,j1] 这段区间后一起消去即可
  1. 那我们用 f i , j f_{i,j} fi,j 表示消去这段区间需要的最少次数,那我们可以得到以下转移方程:
  • { f i , j = m i n ( f i , k + f k + 1 , j ∣ i ≤ k < j ) a i ≠ a j f i , j = m i n ( m i n ( f i , k + f k + 1 , j ∣ i ≤ k < j ) , f i , j , f i + 1 , j − 1 ) a i = a j \begin{cases} f_{i,j} = min(f_{i,k} + f_{k + 1,j}|i \leq k < j) & a_i \ne a_j \\ f_{i,j} = min(min(f_{i,k} + f_{k + 1,j}|i \leq k < j),f_{i,j},f_{i + 1,j - 1}) & a_i = a_j \end{cases} {fi,j=min(fi,k+fk+1,jik<j)fi,j=min(min(fi,k+fk+1,jik<j),fi,j,fi+1,j1)ai=ajai=aj
  1. 我们发现,这种状态转移是以区间为基础的,这种DP通常称作区间DP
  2. 区间DP的解法一般固定,一般是枚举区间长度,然后枚举左端点,最后枚举区间断点。时间复杂度为 o ( n 3 ) o(n^3) o(n3)

2.2 基本概念

  1. 合并:将两个及以上的区间通过一定方式进行整合,也可以反过来操作。
  2. 特征:能将问题分解成两两合并的形式。
  3. 求解:对整个问题设最优值,枚举合并点,将问题分解成左右两部分,最后合并两部分的最优解得到原问题的最优解,有点类似于分治的思想。

2.3 例题分析

本处采用石子合并作为例题分析。

2.3.1 题意解释

  • n n n 个石子沿着一个环分布,现在要将石子有次序的合成一堆。
  • 规定每次只能选择相邻的石子,并将新的一堆的石子数计为该次合并的得分
  • 要求得到两种合并策略,使得最后的得分最大和最小
  • 1 ≤ n ≤ 200 1 \leq n \leq 200 1n200

2.3.2 环的处理

考虑到题目中出现了环,那么我们该如何处理呢?
我们可以将链延长两倍,扩展成 2 × n − 1 2 \times n - 1 2×n1堆,其中第 i i i 堆与第 n + i n+i n+i堆完全相同,然后我们再转以后分别枚举 d p i , n , d p 2 , n + 1 , . . . , d p n , 2 n − 1 dp_{i,n},dp_{2,n+1},...,dp_{n,2n-1} dpi,n,dp2,n+1,...,dpn,2n1,并取其中的最大值即可。
时间复杂度是 O ( 8 n 3 ) O(8n^3) O(8n3) 符合本题的要求,一般是区间DP出现环时最好的处理方法

2.3.3 题目思路

  1. 考虑到如果第 l l l 和第 r r r 堆石子被合并,那么 [ l , r ] [l,r] [l,r] 之间的石子应当也被合并,所以我们可以在任何时刻用 [ l , r ] [l,r] [l,r] 这一个区间来表示任意一堆石子,代表他们是由 [ l , r ] [l,r] [l,r]之间的石子所合并来的。
  2. 同时也存在一个 k k k,使得 [ l , k ] [l,k] [l,k] [ k + 1 , r ] [k+1,r] [k+1,r]之间的石子能分别被合并。
  3. 那么我们就可以用 f i , j f_{i,j} fi,j 表示从第 i i i 堆石子合并到第 j j j 堆石子的最大(最小)值,通过对左右端点对区间的表示,我们可以得到以下转移方程(以最大值为例):
  • f i , j = m a x ( f i , k + f k + 1 , j + s u m j − s u m i − 1 ∣ i ≤ k ≤ j − 1 ) f_{i,j} = max(f_{i,k} + f_{k + 1,j} +sum_j - sum_{i - 1}|i \le k \le j - 1) fi,j=max(fi,k+fk+1,j+sumjsumi1ikj1)

在此处 s u m i sum_i sumi 表示从第 1 1 1 堆石子到第 i i i 堆石子数的总和。

2.3.4 主要代码

for(int p=1;p<n;p++) {  
        for(int i=1,j=i+p;(j<n+n) && (i<n+n);i++,j=i+p)  {  
            f2[i][j] = 999999999;  
            for(int k=i;k<j;k++)  {  
                f1[i][j] = max(f1[i][j], f1[i][k]+f1[k+1][j]+d(i,j));   
                f2[i][j] = min(f2[i][j], f2[i][k]+f2[k+1][j]+d(i,j));  
            }  
        }  
    }  

2.4 推荐例题

P1063 [NOIP2006 提高组] 能量项链
P3146 [USACO16OPEN] 248 G
P4767 [IOI2000] 邮局 加强版

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

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

相关文章

【机器学习西瓜书学习笔记——规则学习】

机器学习西瓜书学习笔记【第十五章】 第十五章 规则学习15.1 基本概念15.2 序贯覆盖最简单的做法两种产生规则的策略 15.3 剪枝优化预剪枝后剪枝 15.4 一阶规则学习**FOIL算法** 15.5 归纳逻辑程序设计( I L P ILP ILP)最小一般泛化逆归结 第十五章 规则学习 15.1 基本概念 规…

干货|嵌入式分析产品选型指南

在当今数据驱动的商业环境中&#xff0c;业务系统的嵌入式分析能力正成为企业决策的关键能力。将数据分析能力嵌入到企业的核心业务流程中&#xff0c;能够帮助企业快速洞察业务趋势&#xff0c;做出更加明智的业务决策。随着市场对数据分析工具的需求日益增长&#xff0c;选择…

本地生活服务平台源码在哪里?2大获取渠道源码质量解析!

当前&#xff0c;本地生活赛道的发展潜力和收益前景已经日渐显化&#xff0c;本地生活服务商的数量也随之不断增长。不过&#xff0c;由于官方平台对于其本地生活服务商的申请条件并未放宽&#xff0c;因此&#xff0c;新增本地生活服务商中的绝大多数都会选择部署本地生活服务…

letcode 分类练习 654. 最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树

letcode 分类练习 654. 最大二叉树 617.合并二叉树 700.二叉搜索树中的搜索 98.验证二叉搜索树 654. 最大二叉树617.合并二叉树700.二叉搜索树中的搜索98.验证二叉搜索树 654. 最大二叉树 class Solution { public:TreeNode* build(vector<int>& nums, int left, int…

Spring MVC中获取请求参数的方式

在Spring MVC中获取请求方式参数的主要方式有RequestParam&#xff0c;PathVariable&#xff0c;RequestBody&#xff0c;HttpServletRequest&#xff0c;RequestHeader等方式&#xff0c;接下来我们分别对其请求获取参数的方式进行相关介绍和使用。 RequestParam 用于获取请…

AMR 机器人底盘分析(补充中)

AMR 机器人底盘分析 1 介绍2 不同轮系底盘类型单舵轮双舵轮底盘四舵轮底盘麦克纳姆轮底盘两驱差速底盘四驱差速底盘单差速总成四差速总成底盘 3 行业专利分析CN220701198U -- 某柔CN110758038A谋星翼*菲谋工 参考 1 介绍 AGV 广泛应用于物流、制造业、安防巡检等领域&#xff…

C语言部分内存函数详解

C语言部分内存函数详解 前言1.memcpy1.1基本用法1.2注意事项**目标空间与原空间不能重叠****目标空间原数据会被覆盖****目标空间要够大****拷贝字节数需小于原空间大小** 1.3模拟实现 2.memmove2.1基本用法2.2注意事项2.3模拟实现 3.memset3.1基本用法 4.memcmp4.1基本用法4.2…

C#使用onnxruntime加载模型,部署到别人的PC上报错

C#使用onnxruntime加载模型&#xff0c;部署到别人的PC上报错 C#使用onnxruntime加载模型&#xff0c;部署到别人的PC上报错解决方案 C#使用onnxruntime加载模型&#xff0c;部署到别人的PC上报错 C#使用onnxruntime加载模型&#xff0c;部署到别人的PC上报错&#xff1a; Sys…

Python Web 应用和数据处理任务库之Redis Queue (RQ) 使用详解

概要 在现代 Web 应用和数据处理任务中,后台任务处理是一个非常重要的部分。Redis Queue (RQ) 是一个使用 Redis 作为消息队列的简单 Python 库,专注于处理异步任务。RQ 易于设置和使用,适用于需要后台处理的 Web 应用或数据处理项目。本文将详细介绍 RQ 库,包括其安装方法…

火狐如何离线继承配置

陪伴自己6年的电脑&#xff0c;因为CPU烧了&#xff0c;导致一些配置没导出来&#xff0c;其中包括浏览器的收藏记录、网站密码。 火狐浏览器离线继承配置 把老电脑的C盘取出&#xff0c;插入硬盘盒中&#xff0c;找到C:\Users\用户名\AppData\Roaming\Mozilla\Firefox\Profile…

【MySQL】JDBC的基础使用

系列文章目录 第一章 数据库基础 第二章 数据库基本操作 第三章数据库约束 第四章表的设计 第五章查询进阶 第六章索引和事务 文章目录 系列文章目录前言一、JDBC基本概念二、JDBC的准备工作三、JDBC-Demo小结 四、JDBC进阶写法总结 前言 在前面对MySQL已经有了基本的认知&am…

分类预测|基于白鲸优化混合核极限学习机结合Adaboost的数据分类预测Matlab程序BWO-HKELM-Adaboost

分类预测|基于白鲸优化混合核极限学习机结合Adaboost的数据分类预测Matlab程序BWO-HKELM-Adaboost 文章目录 前言分类预测|基于白鲸优化混合核极限学习机结合Adaboost的数据分类预测Matlab程序BWO-HKELM-Adaboost 一、BWO-HKELM-Adaboost模型1. 模型组成1.1 白鲸优化算法&#…

Arco Design,字节跳动出品的UI库

Arco Design是字节跳动出品的UI库&#xff0c;支持Vue和React。还是比较美观的。并且Arco Design还提供了中后台模版。但是通过提供的arco-cli连接了github&#xff0c;正常情况下无法构建。但效果还是挺好的&#xff0c;下面是效果图&#xff1a; 更新&#xff1a; 传送门可…

用C#写一个随机音乐播放器

form1中namespce里的代码如下 public partial class Form1 : Form {public Form1(){InitializeComponent();}private void button1_Click(object sender, EventArgs e){string folder textBox1.Text;string folderPath folder; // 指定音频文件所在的文件夹路径OpenRandomFi…

C#关于多线程的线程问题

using System.Text; ​ namespace 平时练习8._19day06 {internal class Program{static async Task Main(string[] args){Console.WriteLine(Thread.CurrentThread.ManagedThreadId );StringBuilder sb new StringBuilder();for (int i 0; i < 10000; i){sb.Append("…

嵌入式系统:全面解读与关键要点

嵌入式系统&#xff0c;这个看似专业而遥远的技术词汇&#xff0c;其实早已渗透进了我们日常生活的方方面面。从智能手机到家用电器&#xff0c;再到汽车中的电子控制系统&#xff0c;嵌入式系统无处不在。你是否好奇它们是如何工作的&#xff0c;又有哪些关键点值得我们关注&a…

Android12 显示框架之Transaction----client端

目录&#xff1a;Android显示终极宝典 在前面的章节中&#xff0c;应用通过createSurface()在surfaceflinger中创建了一层layer&#xff0c;紧接着要做的事情就是对这个layer设置一些属性&#xff08;或者叫状态&#xff09;&#xff0c;常设置的属性有位置、大小、z-order等等…

RM悬挂系统

悬挂系统是汽车的车架与车桥或车轮之间的一切传力连接装置的总称&#xff0c;其作用是传递作用在车轮和车架之间的力和力扭&#xff0c;并且缓冲由不平路面传给车架或车身的冲击力&#xff0c;并衰减由此引起的震动&#xff0c;以保证汽车能平稳地行驶。 其主要由减震器和弹簧组…

PictureSelector自定义路径首页不显示数据的问题

1、依赖导入和源码查看 网址&#xff1a;https://github.com/LuckSiege/PictureSelector/tree/version_component 使用PictureSelector 2、自定义路径的实现&#xff1a; 使用方法&#xff1a;setLoaderFactoryEngine进行设置 见[read.md] (https://github.com/LuckSiege/Pi…

C++ wxWidgets图形界面开发用什么IDE最好?

在主流免费的IDE工具中&#xff0c;我们可以想到的支持cmake项目的工具就只有QtCreator&#xff0c;VisualStudio&#xff0c;VSCode这三个。其中QtCreator和VSCode支持WIndows&#xff0c;Mac&#xff0c;WIndows三大主流平台。但是VSCode在Ubuntu等系统下的支持并没有在WIndo…