五大基础dp
动规条件
• 最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,
即满足最优化原理。
• 无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后
的过程不会影响以前的状态,只与当前状态有关。
• 有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。
(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法
相比就不具备优势)
背包dp
- 01背包 (一件物品只能选一次)
https://tg.hszxoj.com/contest/897/problem/1
点击查看代码
for(int i=1; i<=n; i++){//外层循环物品
for(int j=V; j>=v[i]; j--){//内层循环体积 倒叙循环
dp[j] = max(dp[j], dp[j-v[i]] + w[i];
}
}
- 完全背包 (不限制物品数量)
https://tg.hszxoj.com/contest/897/problem/4
点击查看代码
for(int i=1; i<=n; i++){//外层循环物品
for(int j=v[i]; j<=V; j++){//内层循环体积 顺叙循环
dp[j] = max(dp[j], dp[j-v[i]] + w[i]);
}
}
//二进制拆分
for(int i=1; i<=n; i++){
for(int k=1; k<=V/v[i]; k<<=1){
for(int j=V; j>=k*v[i]; j--){
dp[j] = max(dp[j], dp[j-k*v[i]] + k*w[i]);
}
}
}
- 多重背包 (给定物品数量)
https://tg.hszxoj.com/contest/897/problem/6
点击查看代码
//与完全背包一样使用二进制拆分
if(si > m / vi) si = m / vi;
for(int j=1; j<=si; j<<=1){
v[++cnt] = j * vi;
w[cnt] = j * wi;
si -= j;
}
if(si){
v[++cnt] = si * vi;
w[cnt] = si * wi;
}
}
n = cnt;
- 混合背包
https://tg.hszxoj.com/contest/897/problem/11
将背包都使用二进制拆分转成01包计算
- 分组背包
https://tg.hszxoj.com/contest/897/problem/13
点击查看代码
a[p][++a[p][0]] = i;//a[p][0]是每组个数
for(int p=1; p<=t; p++){
for(int j=v; j>=w[a[p][i]]; j--){
for(int i=1; i<=a[p][0]; i++){
f[j] = max(f[j], f[j-w[a[p][i]]] + c[a[p][i]]);
}
}
}
- 二维费用背包
NASA的食物计划
https://tg.hszxoj.com/contest/897/problem/12
只需要把dp数组改成二维,第一维表示质量,第二维表示卡路里即可
点击查看代码
for(int i=1; i<=n; i++){
for(int j=x; j>=v[i]; j--){
for(int a=y; a>=m[i]; a--){
f[j][a] = max(f[j][a], f[j-v[i]][a-m[i]] + k[i]);
}
}
}
线性dp
顾名思义,线性DP就是在一条线上进行DP
例如:
最长上升序列
https://tg.hszxoj.com/contest/900/problem/1
点击查看代码
for(int i=1; i<=n; i++){
dp[i] = 1;
for(int j=1; j<i; j++){
if(a[i] > a[j] and dp[i] < dp[j] + 1){
dp[i] = dp[j] + 1;
pre[i] = j;//记录前一位,方便输出
}
}
if(ans < dp[i]){
ans = dp[i];
en = i;//记录结点
}
}
//递归输出
void p(int x){
if(!x) return;
p(pre[x]);
cout << a[x] << ' ';
}
//由结点开始递归即可
拦截导弹
https://tg.hszxoj.com/contest/900/problem/3
点击查看代码
for(int i=1; i<=n; i++){
f[i] = 1;
for(int j=1; j<i; j++){
if(a[i] <= a[j]){
f[i] = max(f[i], f[j] + 1);
}
}
ans = max(ans, f[i]);
}
区间dp
这里实际上是以区间长度为阶段的,这种DP我们通常称为区间DP。
区间DP的做法较为固定,即枚举区间长度,再枚举左端点,之后枚举区间的断点进行转移。
区间类型动态规划是线性动态规划的拓展,它在分阶段划分问题时,与阶段中元素出现的顺序和由前一阶段的哪些元素合并而来有很大的关系。(例:f[i][j]=f[i][k]+f[k+1][j])
区间类动态规划的特点:
- 合并:即将两个或多个部分进行整合。
- 特征:能将问题分解成为两两合并的形式。
- 求解:对整个问题设最优值,枚举合并点,将问题分解成为左右两个部分,最后将左右两个部分的最优值进行合并得到原问题的最优值。
石子合并<3>
https://tg.hszxoj.com/contest/903/problem/3
点击查看代码
for(int i=1; i<=n*2; i++){//环状就弄成二倍串
s[i] = s[i-1] + a[i];//求前缀和
}
for(int l=2; l<=n; l++){
for(int i=1; i+l-1<=n*2; i++){
int j = i + l - 1;
g[i][j] = max(g[i+1][j], g[i][j-1]) + s[j] - s[i-1];
}
}
坐标dp
坐标型dp一般都是给定网格、序列,来求满足某种性质的最大值、最小值。f[i][j]代表以i、j结尾的满足条件的某种情况。
晴天小猪历险记之Hill
https://tg.hszxoj.com/contest/906/problem/5
点击查看代码
dp[1][1] = s[1][1];
for(int i=2; i<=n; i++){
for(int j=1; j<=i; j++){//从上到下遍历
dp[i][j] = min(dp[i-1][j], dp[i-1][j-1]) + s[i][j];
dp[i][1] = min(dp[i-1][1], dp[i-1][i-1]) + s[i][1];
dp[i][i] = min(dp[i-1][i-1], dp[i-1][1]) + s[i][i];
}
for(int j=i-1; j>=1; j--){//从右到左遍历
dp[i][j] = min(dp[i][j], dp[i][j+1] + s[i][j]);
dp[i][i] = min(dp[i][i], dp[i][1] + s[i][i]);
}
for(int j=2; j<=i; j++){//从左到右遍历
dp[i][j] = min(dp[i][j], dp[i][j-1] + s[i][j]);
dp[i][1] = min(dp[i][1], dp[i][i] + s[i][1]);
}
}
树形dp
树形DP的特殊性:没有环,dfs是不会重复,而且具有明显而又严格的层数关系。利用这一特性,我们可以很清晰地根据题目写出一个在树(型结构)上的搜索的程序。而深搜的特点,就是“不撞南墙不回头”
没有上司的舞会
https://tg.hszxoj.com/contest/909/problem/1
使用链表加边,随后dfs进行搜索
dp[x][0] 表示自己不参加 dp[x][1] 表示自己参加
点击查看代码
void dfs(int x){
for(int i=h[x]; i; i=nxt[i]){
int y = to[i];
dfs(y);
dp[x][0] += max(dp[y][1], dp[y][0]);//直接上司不参加, 则下属是否参加取较大值
dp[x][1] += dp[y][0];//直接上司参加,则下属一定不参加
}
}
初始化时注意参加即为自己的快乐值,不参加则为0
搜索时从根节点开始搜
五大基础dp的更多相关文章
- IT运维的五大基础知识
IT运维的五大基础知识 | 浏览:331 | 更新:2014-09-25 11:36 IT运维对于很多企业都很重要,接下来运维的一些基础知识天天客服IT运维总监龙少文,就给大家介绍下IT运维的基础知识 ...
- 基础dp
队友的建议,让我去学一学kuangbin的基础dp,在这里小小的整理总结一下吧. 首先我感觉自己还远远不够称为一个dp选手,一是这些题目还远不够,二是定义状态的经验不足.不过这些题目让我在一定程度上加 ...
- 基础DP(初级版)
本文主要内容为基础DP,内容来源为<算法导论>,总结不易,转载请注明出处. 后续会更新出kuanbin关于基础DP的题目...... 动态规划: 动态规划用于子问题重叠的情况,即不同的子问 ...
- hdu 5586 Sum 基础dp
Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Desc ...
- hdu 4055 Number String (基础dp)
Number String Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 训练指南 UVA - 10917(最短路Dijkstra + 基础DP)
layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: tr ...
- 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP)
layout: post title: 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP) author: "luowentaoaa" catalog: true ...
- 「kuangbin带你飞」专题十二 基础DP
layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...
- M - 基础DP
M - 基础DP Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descriptio ...
- lightoj1004【基础DP】
从低端到顶端求个最大值: 思路: 基础DP,递推 #include<cstdio> #include<queue> #include<map> #include&l ...
随机推荐
- 5个前端开源项目带你在Web上体验Windows
本文来分享五个 yyds 的开源项目,这些项目把 Windows 带到了 Web 平台上.让我们一起感受这些项目带来的回忆和创新,重温 Windows 93.98.XP 和 7 的经典界面,甚至探索现 ...
- Win10已死!微软发布Windows 11大更新:引入ChatGPT、升级巨大
今天凌晨微软在开发者大会上公布了Windows 11的新版本更新"Moment 3",整体升级幅度非常的大. 新系统的多任务有了改进,现在按下Alt+Tab时,可以显示更多的Edg ...
- 错误: tensorflow.python.framework.errors_impl.OutOfRangeError的解决方案
近日,在使用CascadeRCNN完成目标检测任务时,我在使用这个模型训练自己的数据集时出现了如下错误: tensorflow.python.framework.errors_impl.OutOfRa ...
- TValue 的 TTypeKind 的自动转换
首先官方的定义: TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkClass ...
- 如何在windows端安装和配置maven
1.下载maven 从官方下载maven,下载页面:http://maven.apache.org/download.cgi 2.安装maven maven压缩包解压到一个没有中文,空格或其他特殊字符 ...
- JS leetcode II. 左旋转字符串 题解分析
壹 ❀ 引 简单的题目简单做,本题来自leetcode面试题58 - II. 左旋转字符串,题目描述如下: 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部.请定义一个函数实现字符串左旋 ...
- useMemo与useCallback
useMemo与useCallback useMemo和useCallback都可缓存函数的引用或值,从更细的角度来说useMemo则返回一个缓存的值,useCallback是返回一个缓存函数的引用. ...
- dllimport 和 dllexport
Dll 在需要暴露接口的头文件里添加 dllexport 声明,比如, #define DllExport __declspec( dllexport ) class DllExport C { in ...
- Direct2D 旋转篇
微软文档:Transforms 本篇通过官方文档学习,整理出来的demo,初始样本请先创建一个普通的desktop app. ID2D1SolidColorBrush* m_pOriginalShap ...
- 硬件开发笔记(七): 硬件开发基本流程,制作一个USB转RS232的模块(六):创建0603封装并关联原理图元器件
前言 有了原理图,可以设计硬件PCB,在设计PCB之间还有一个协同优先动作,就是映射封装,原理图库的元器件我们是自己设计的.为了更好的表述封装设计过程,本文描述了贴片电阻电容0603芯片封装,创建 ...