当前位置: 首页 > news >正文

【OI复健-DP-1】线性DP背包DP

线性 DP

线性 DP 一般是状态只有一维的 DP。

DP 一般是用于解决这样的一些问题:每一个子任务都具有相同的结构,同时我们只关心当前的状态是什么,不关系如何转移到这个状态的。

最长上升子序列

给定一个长度为 \(n\) 的序列 \(a\),求这个序列的最长上升子序列。

\(f_i\) 表示以 \(i\) 结尾的最长上升子序列长度,对于每一个 \(i\),枚举它的上一个元素是什么,\(f_i=(\max\limits_{a_j<a_i}) f_j + 1\).

洛谷 3842 / TBOJ1894 线段

显然我们只会走到每一行的线段左右端点位置,然后就停下来进入下一行。设 \(f_{i,0/1}\) 表示走完第 \(i\) 行,当前在左/右端点的最小答案。

转移只需要考虑从 \(i-1\)\(i\) 要走多少步就好。

const int MAXN = 2e4 + 5;
int n, l[MAXN], r[MAXN], f[MAXN][2];void work() {cin >> n;for (int i = 1; i <= n; ++i) cin >> l[i] >> r[i];l[0] = r[0] = 1;for (int i = 1; i <= n; ++i) {f[i][0] = min(f[i - 1][0] + (i != 1) + abs(r[i] - l[i - 1]) + r[i] - l[i],f[i - 1][1] + (i != 1) + abs(r[i] - r[i - 1]) + r[i] - l[i]);f[i][1] = min(f[i - 1][0] + (i != 1) + abs(l[i] - l[i - 1]) + r[i] - l[i],f[i - 1][1] + (i != 1) + abs(l[i] - r[i - 1]) + r[i] - l[i]);}int ans = min(f[n][0] + n - l[n], f[n][1] + n - r[n]);cout << ans << endl;
}

洛谷 1541 / TBOJ1410 乌龟棋

\(f_{i,j,k,h}\) 表示当前用了 \(i/j/k/h\) 张 1/2/3/4 牌,能拿到的最多价值,当前位置显然为 \(i+2j+3k+4h\),转移枚举一下用了哪张牌到达的当前位置,即:\(f_{i,j,k,h}=\min f_{i',j',k',h} + a_{i+2j+3k+4h}\)

背包 DP

这个东西板子考的不多,大概意思是有 \(n\) 个物品,背包容量为 \(m\),每个物品有一个价值 \(v_i\) 和重量 \(w_i\),要求在选出的物品重量之和不超容量的情况下最大化价值。

\(f_{i,j}\) 表示考虑前 \(i\) 个物品,当前最大容量为 \(j\) 的最大价值,每次转移枚举一下选不选 \(i\) 这个物品即可。

洛谷 1048 / TBOJ2350 采药

01 背包板子。

洛谷 1616 / TBOJ3454 疯狂的采药

完全背包板子。

洛谷 6771 / TBOJ4724 太空电梯

\(f_{i,j}\) 表示考虑前 \(i\) 个方块,能不能达到高度 \(j\),每次转移就枚举当前方块选几个。

可能需要把第一维给滚动掉。

abc267d / TBOJ4725 Index × A(Not Continuous ver.)

\(f_{i,j}\) 表示当前考虑前 \(i\) 个元素,选了 \(j\) 个,转移就枚举当前这个元素选/不选。

#define int long long
const int MAXN = 2e3 + 5;
int n, m, a[MAXN], f[MAXN][MAXN];void work() {cin >> n >> m;for (int i = 1; i <= n; ++i) cin >> a[i];for (int i = 0; i <= n; ++i) {for (int j = 1; j <= m; ++j) f[i][j] = LLONG_MIN / 2;}for (int i = 1; i <= n; ++i) {for (int j = 1; j <= m; ++j) {f[i][j] = max(f[i - 1][j], f[i - 1][j - 1] + a[i] * j);}}cout << f[n][m] << endl;
}

abc245c / TBOJ4726 Choose Elements

\(f_{i,0/1}\) 表示考虑前 \(i\) 个元素,第 \(i\) 个位置上选了 \(a/b\),是否有一个合法序列。转移枚举当前位置选 \(a\) 还是选 \(b\) 即可。

const int MAXN = 2e5 + 5;
int n, k, a[MAXN], b[MAXN];
bool f[MAXN][2];void work() {cin >> n >> k;for (int i = 1; i <= n; ++i) cin >> a[i];for (int i = 1; i <= n; ++i) cin >> b[i];f[1][0] = f[1][1] = true;for (int i = 2; i <= n; ++i) {if (abs(a[i] - a[i - 1]) <= k) f[i][0] |= f[i - 1][0];if (abs(a[i] - b[i - 1]) <= k) f[i][0] |= f[i - 1][1];if (abs(b[i] - a[i - 1]) <= k) f[i][1] |= f[i - 1][0];if (abs(b[i] - b[i - 1]) <= k) f[i][1] |= f[i - 1][1];}cout << ((f[n][0] || f[n][1]) ? "Yes" : "No") << endl;
}
http://www.sczhlp.com/news/1943/

相关文章:

  • 融合字符切割与深度卷积网络的多字符验证码识别方法
  • java第三十天
  • 面试题记录:spring boot 启动流程 + 如何处理循环依赖
  • Day3 拉格朗日乘数法
  • 【leetcode刷题】动态规划 Part 5 划分型DP
  • 20250730
  • 语义差异对比工具Graphtage:超越传统diff的新选择
  • 验证随意小记20250730-UVC
  • 第十篇:全链路监控
  • 项目分析步骤
  • 25
  • 可达 2025 暑期集训笔记:CSP-S 沃斯班
  • 在Docker中,如何实现退出容器时候自动删除?
  • AI Compass前沿速览:可灵创意工坊、字节Coze StudioCoze Loop、通义万相2.2 、智谱GLM-4.5、腾讯混元3D世界模型开源
  • 5.8 循环展开
  • 7.30读后感
  • 线性基
  • 深入解析:循环神经网络(RNN)详解:从原理到实践
  • 在Docker中,怎么快速查看本地的镜像和容器?
  • CF555E Case of Computer Network
  • 在Docker中,如何停止所有正在运行的容器?
  • 在Docker中,容器退出后,通过docker ps命令查看不到,数据会丢失么?
  • 莫反推式子trick
  • 在Docker中,如何更改Docker的默认存储设置?
  • 在Docker中,如何批量清理后台停止的容器?
  • 基于Redisson和自定义注解的分布式锁
  • server - 陈飞
  • 【NCS随笔】如何在hello_world添加蓝牙功能(一)
  • Java基础语法学习 ———— Day2
  • system - 陈飞