首页 > 其他分享 >动态规划基础

动态规划基础

时间:2023-08-05 16:48:14浏览次数:97  
标签:动态 凑出 基础 step 背包 序列 例题 规划 dp

引入

动态规划简介

  • 动态规划 \(dp=Dynamic \ Programming\)
  • 线性 \(dp\):状态定义与题设线性相关
  • 将原问题分解成若干子问题
  • 设计状态:状态是当前问题所在的局面
  • 满足性质:无后效性,最优子结构
  • 转移:状态之间的关系,用转移方程描述
  • 动态规划(递推)记忆化搜索(递归) 时间复杂度相同
    • 记忆化搜索可以规避转移顺序,且方便处理边界情况
    • 记忆化搜索效率较低,且难以优化、调试

例子:最长上升子序列

  • 状态:以第 \(x\) 个元素结尾的最长上升子序列(\(LIS\))的长度,用 \(f_x\) 表示
  • 转移:最长上升子序列一定是接在某个上升子序列尾部形成的
  • 刻画整体的转移路径:
    • 把每一个状态视作一个节点,把状态转移视作一条有向边,串联起来构成有向无环图(\(DAG\))
    • 所以根据拓扑序对图进行遍历来求解问题(拓扑排序)
    • 动态规划遍历顺序称为阶段

动态规划三要素

  • 状态(描述问题局面)
  • 转移(状态之间的数学关系)
  • 阶段(计算状态的顺序)

B3635 硬币问题

  • 题意简述:用 \(1, \ 5, \ 11\) 元的硬币凑出 \(n\) 元,最少需要多少硬币?
  • 状态:\(dp_n\) 表示凑出 \(n\) 元所需要的最少硬币数量
  • 转移:\(dp_i = min(dp[i-1], dp[i-5], dp[i-11]) + 1\)
  • 解释:凑出 \(n\) 元有三种局面
    • 凑出 \(n-1\) 元,拿出一个 \(1\) 元硬币
    • 凑出 \(n-5\) 元,拿出一个 \(5\) 元硬币
    • 凑出 \(n-11\) 元,拿出一个 \(11\) 元硬币
    • 取三个当中的最小值

一维线性 \(dp\)

例题:P1091

  • 使用 \(dp\) 求出 LIS 和 LDS,枚举中间最高的那个人

优化最长上升子序列

  • 第一种枚举时间复杂度 \(O(n^2)\),但存在大量重复枚举
  • 记录以前选的所有数的下标,对于元素 \(x\)
    • 如果 \(x\) 小于最大值,那么替换掉第一个大于它的数
    • 如果 \(x\) 大于最大值,那么插入到最后
  • 优化后时间复杂度 \(O(n \ log \ n)\)

二维线性 \(dp\)

例题:P1216

  • 状态:设 \(f[i][j]\) 表示到了位置 \((i,j)\) 时可以得到的最大数字和
  • 转移:\(f[i][j]=max(f[i-1][j-1], f[i-1][j])+a[i][j]\)

例子:最长公共子序列

  • 给定两个序列 \(A,B\),求最长公共子序列(\(LCS\))的长度

优化前

  • 状态:\(f[i,j]\) 表示第一个排列前 \(i\) 个元素和第二个排列前 \(j\) 个元素,最长公共子序列的长度
  • 转移:$$f[i,j]=f[i-1][j-1]+1,A_i=B_j$$

\[f[i,j]=max(f[i-1][j],f[i][j-1]),A_i≠B_j \]

\[f[i][j]=\begin{cases} f[i-1][j-1]+1 & A[i]=B[j] \\ max(f[i-1][j],f[i][j-1]) & A[i]≠B[j] \end{cases} \]

优化后

  • 重新标号:把 \(A\) 用字母标成单调递增数列,再用这样的标号标记 \(B\),求 \(B\) 的最长上升序列

例题:P1004

  • \(f[step][a][b][x][y]\) 表示走了 \(step\) 步,甲走到 \((a,b)\),乙走到 \((x,y)\)
  • 把 step 一维省略:变为四维 dp
  • \(f[step][a][b][x][y]=走到当前格对答案的贡献+\)
    • \(f[step][a-1][b][x-1][y]\)
    • \(f[step][a-1][b][x][y-1]\)
    • \(f[step][a][b-1][x-1][y]\)
    • \(f[step][a][b-1][x][y-1]\)

背包 \(dp\)

01 背包(一个物品只能选择一次)

  • \(w\) 表示重量,\(v\) 表示价值,\(N\) 表示物品个数,\(W\) 表示背包容量,\(f\) 表示 \(dp\) 数组
  • 注意:第二层循环必须从大到小枚举
for (int i = 1; i <= N; i ++) {
    for (int j = W; j >= w[i]; j --)
        f[j] = max(f[j], f[j - w[i]] + v[i]);
}

完全背包(每个物品可以无限次选择)

for (int i = 1; i <= N; i ++) {
    for (int j = w[i]; j <= W; j ++)
        f[j] = max(f[j], f[j - w[i]] + v[i]);
}

多重背包(每个物品可以选择 \(k_i\) 次)

  • 第一种:转换成 01 背包
    • 时间复杂度 \(O(nW\sum k_i)\)
  • 第二种(二进制优化):把每个 \(k\) 拆成二进制表示,即\(1+2+4+...+2^n\),变成了 \(log \ k_i\),再进行 01 背包
    • 时间复杂度 \(O(nW\sum log \ k_i)\)

混合背包例题:P1833

  • 由于总时间有限,把完全背包的无限次转化为 \(1000\) 次
  • 01 背包就是多重背包中的 \(k=1\)

分组背包例题:P1757

  • 物品被划分成 \(k\) 组,每一组内只能选择最多 \(1\) 个物品
  • 组内先枚举物品重量,再内聚物品编号
  • 共三维:组、重量、编号

依赖背包例题:P1064

  • 每一种主件的四种情况
    • 只购买主件
    • 购买主件,附件 A
    • 购买主件,附件 B
    • 购买主件,附件 AB

区间 \(dp\)

区间 \(dp\) 介绍

  • 在区间上做动态规划,求在区间上的最优解
  • 区间 \(dp\) 的状态通常包括区间信息 \((l,r)\)
  • 子区间信息满足区间加法
  • 分治思想:大区间信息由小区间获得

区间 \(dp\) 例题:P1775

对环形问题的处理

  • 使用破环成链的思想
  • 将数组倍长,令 \(a[i+n]=a[i]\)

环上 \(dp\) 例题:P1063

  • \(f[l][r]\) 表示将 \([l,r]\) 范围内全部能量珠合并释放的最大能量,可得 \(f[l][r]=max(f[l][k]+f[k+1][r]+a[l]×b[i]×b[r])\)

标签:动态,凑出,基础,step,背包,序列,例题,规划,dp
From: https://www.cnblogs.com/winter-tide/p/17608146.html

相关文章

  • 【更新中】【Unity/UE】基础仿原神渲染
    前言【本文持续更新中】终于把一直想做一做的仿原神渲染做了一下。原神出来也有段时间了,各路大佬的逆向早就做完了,所以最近做的其实复刻大佬们的工程,难度并不大。废话不多说,先看效果。Unity UE (UE的边缘光老是闪就关了) 两个版本都没有加上雾效,泛光之间的后处理效果,......
  • vps折腾记三vps的基础防护
    1.更新软件保持软件最新可以防止旧软件的漏洞,保证系统更加安全#列出可更新的软件yumcheck-update#更新所有可更新的软件yumupdate2.ROOT修改强密码非法分子会自动扫描IP地址,SSH的默认端口是22,用户肯定有root,所以只有密码是非法分子不知道,保持强密码可以防止暴力破解......
  • Mybatis-Flex之基础查询
    1、selectOneById/***selectOneById(id):根据主键查询数据。*/@TestpublicvoidtestSelectOneById(){/***SELECT*FROM`tb_account`WHERE`id`=?*/Accountaccount=accountMapper.selectOneById(10L);......
  • VxeTable 列动态数据过滤 FilterContent
    1、加入组件,并注册:下载官网实例将VxeTable的v4下的位置中的画框的几个都拷到自己的项目中,然后打开filter.tsx,将组件的引用路径调整自己的项目一致,如果是一样就不改了。这一步,要保证filter.tsx中引用到4个vue文件就可以。  2、引入到项目中,保证项目能读到filter.tsx,这样就......
  • 电气工程师基础知识
    这些基础知识在大学里面都学过,只是后面转软件开发后很多都忘了。这里专门写一篇文章做备忘录,文章会持续更新增加内容。NPN与PNP针对输入侧只要确定:公共端子为电源-,则为漏型输入,接PNP接近开关;公共端子为电源+,则为源型输入,接NPN接近开关。针对输出侧只要确定:M(N)端子为电源......
  • 【python_6】基础语法:标识符和运算符!
    1.什么是标识符在python程序中,我们可以给很多东西起名字,比如:变量的名字方法的名字类的名字等等这些名字,我们把它统一的称之为标识符,用来做内容的标识。所以,标识符:是用户在编程的时候所使用的一系列名字,用于给变量,类,方法等命名。2.标识符的命名规则标识符命名的规则主要有三类内容限......
  • 动态配置与服务屏蔽
    服务提供者:user-service-provider 服务消费者:order-service-consumer 场景一:屏蔽消费者  1.屏蔽后会默认添加一条动态配置2.发起请求后,提供者的服务默认会返回null ......
  • 凸优化8——线性规划、二次规划
    线性规划以及等价变换中科大-凸优化笔记(lec25)-等价变换_凸优化等价_及时行樂_的博客-CSDN博客二次规划QP 二次约束二次规划QCQP中科大-凸优化笔记(lec26)-二次规划_二次约束二次规划_及时行樂_的博客-CSDN博客引入了lasso回归和岭回归......
  • 算法工程师学习运筹学 笔记二 线性规划
    线性规划 框架图先放在这里图片由知乎@运筹说提供,原文链接:https://zhuanlan.zhihu.com/p/382644742  线性规划模型标准型 标准型如上目标函数求max;约束条件两端用“=”连结;右端常数项非负;所有决策变量非负。(如有决策变量没有约束,则把该变量拆成两个正数变量......
  • Linux基础32 nginx多虚拟主机,日志,日志目录模块,访问限制模块
    虚拟主机方式一:基于主机多IP方式基于主机多ip的方式,主机多网卡,多外网ip(一般不使用这种方式)[[email protected]]#catchess.confserver{listen10.0.0.7:80;server_namelocalhost;location/{root/code/chess;indexindex.html;}}[r......