动规条件

最优化原理:如果问题的最优解所包含的子问题的解也是最优的,就称该问题具有最优子结构,

即满足最优化原理。

无后效性:即某阶段状态一旦确定,就不受这个状态以后决策的影响。也就是说,某状态以后

的过程不会影响以前的状态,只与当前状态有关。

有重叠子问题:即子问题之间是不独立的,一个子问题在下一阶段决策中可能被多次使用到。

(该性质并不是动态规划适用的必要条件,但是如果没有这条性质,动态规划算法同其他算法

相比就不具备优势)

背包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]]);
}
}
}
点击查看代码
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的更多相关文章

  1. IT运维的五大基础知识

    IT运维的五大基础知识 | 浏览:331 | 更新:2014-09-25 11:36 IT运维对于很多企业都很重要,接下来运维的一些基础知识天天客服IT运维总监龙少文,就给大家介绍下IT运维的基础知识 ...

  2. 基础dp

    队友的建议,让我去学一学kuangbin的基础dp,在这里小小的整理总结一下吧. 首先我感觉自己还远远不够称为一个dp选手,一是这些题目还远不够,二是定义状态的经验不足.不过这些题目让我在一定程度上加 ...

  3. 基础DP(初级版)

    本文主要内容为基础DP,内容来源为<算法导论>,总结不易,转载请注明出处. 后续会更新出kuanbin关于基础DP的题目...... 动态规划: 动态规划用于子问题重叠的情况,即不同的子问 ...

  4. hdu 5586 Sum 基础dp

    Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Desc ...

  5. hdu 4055 Number String (基础dp)

    Number String Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  6. 训练指南 UVA - 10917(最短路Dijkstra + 基础DP)

    layout: post title: 训练指南 UVA - 10917(最短路Dijkstra + 基础DP) author: "luowentaoaa" catalog: tr ...

  7. 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP)

    layout: post title: 训练指南 UVA - 11324(双连通分量 + 缩点+ 基础DP) author: "luowentaoaa" catalog: true ...

  8. 「kuangbin带你飞」专题十二 基础DP

    layout: post title: 「kuangbin带你飞」专题十二 基础DP author: "luowentaoaa" catalog: true tags: mathj ...

  9. M - 基础DP

    M - 基础DP Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Descriptio ...

  10. lightoj1004【基础DP】

    从低端到顶端求个最大值: 思路: 基础DP,递推 #include<cstdio> #include<queue> #include<map> #include&l ...

随机推荐

  1. Python 实现Ping命令状态检测

    ping 是一种因特网包探索器,用于测试网络连接量的程序,Ping是工作在TCP/IP网络体系结构中应用层的一个服务命令,主要是向特定的目的主机发送 ICMP 请求报文,测试目的站是否可达及了解其有关 ...

  2. (转)时代的见证:集成更新的Windows 7旗舰版、专业版镜像

    制作缘起:微软曾于2019年提供过两份内部集成更新的英文旗舰版.专业版镜像(参见:集成IE11+最新补丁:微软新版Windows 7镜像泄露),方便用户安装,缩短更新过程.经我们下载安装研究发现,这两 ...

  3. P6824 「EZEC-4」可乐 题解

    题目链接:可乐 一开始想着 0-1 Trie,枚举 \(x\) 去写,然后判断就行了.然后想起南京区域赛的 C 题,其实和这个也有点大同小异的感觉,可以用更朴素的办法,找到对于一个 \(a_i\) 而 ...

  4. 基于客户真实使用场景的云剪辑Timeline问题解答与代码实操

    本文为阿里云智能媒体服务IMS「云端智能剪辑」实践指南第6期,从客户真实实践场景出发,分享一些Timeline小技巧(AI_TTS.主轨道.素材对齐),助力客户降低开发时间与成本. 欧叔|作者 故事的 ...

  5. ZR 七连 Day 1 游记

    ZR 七连 Day 1 游记 游记篇 赛前搞笑事件 今天是第一场正睿,还是要 好好对待 的 $ 17:59:58 $ 还在吃饭 $ 17:59:59 $ 做出重要决定,先打着比赛,有空就吃一口包子 $ ...

  6. Codeforces Round #884 (Div. 1 + Div. 2) A-E

    比赛链接 A 代码 #include <bits/stdc++.h> using namespace std; using ll = long long; bool solve() { i ...

  7. NC24911 数独挑战

    题目链接 题目 题目描述 数独是一种填数字游戏,英文名叫 Sudoku,起源于瑞士,上世纪 70 年代由美国一家数学逻辑游戏杂志首先发表,名为 Number Place,后在日本流行,1984 年将 ...

  8. 【Unity3D】Photon环境搭建

    1 简介 ​ Photon 是一个泛用性的 ScoketServer 套装软件,可用于多人在线游戏.聊天室.大厅游戏,并同时支持 Windows.Unity3D.iOS.Android.Flash 等 ...

  9. ORACLE SEQUENCE 详解

    1.    About Sequences(关于序列) 序列是数据库对象一种.多个用户可以通过序列生成连续的数字以此来实现主键字段的自动.唯一增长,并且一个序列可为多列.多表同时使用. 序列消除了串行 ...

  10. java ArrayList排序不区分大小写

    最近在做代码勇士codewars的题目,顺便记录一下自己的解决方案. 1.排序类 1.1 不使用预定义比较器 package com.dylan.practice; import java.util. ...