b站视频链接:北京理工大学ACM冬季培训课程
未找到课程习题
本篇博文为看视频学习时的记录与自己的一些总结
动态规划DP
¶什么是动态规划?
动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决。
¶两个问题
解决动态规划问题,要明确状态和转移两个问题。
¶【例】数字三角形
给出一个数字三角形,从顶点出发每次向下或右下走一步直至最底层,将途经的数字相加,问得到的最大值。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
7->3->8->7->5 = 30
¶状态
定义状态 $f[i][j]$ 表示从 $(1, 1)$ 出发走到 $(i, j)$ 所有路径的最大和。
例如:$f[3][2] = \text{max}(7+3+1, 7+8+1) = 16$
答案从哪取:$f[n][1 \dots n]$
¶转移
考虑哪些状态对 $f[i][j]$ 这个状态有影响。
$(i-1, j) \rightarrow (i, j)$
$(i-1, j-1) \rightarrow (i, j)$
如何转移?
$f[i][j] = \text{max}(f[i-1][j], f[i-1][j-1]) + a[i][j]$
把 $(1, 1)$ 到 $(i, j)$ 的路径分成两类,$(1, 1) \rightarrow (i-1, j) \rightarrow (i, j)$ 和 $(1, 1) \rightarrow (i-1, j-1) \rightarrow (i, j)$
¶初始状态&取答案
状态要明确两点
-
初始状态 $f[1][1] = a[1][1]$,其余为 $-\text{inf}$
-
答案在哪取 $\text{max}(f[n][1] \dots f[n][n])$
转移要注意顺序
从上到下,从左到右
For i:2->n
For j:1->l
f[i][j] = max(f[i-1][j], f[i-1][j-1]) + a[i][j];
¶【例】经典问题最长上升子序列 (LIS)
给一个序列,求它的最长上升子序列。
其中,子序列是指将序列删除 $0 - n$ 个元素所组成的序列,子序列不一定是连续的。
1 13 5 7 8 2 11
1 5 7 8 11
¶状态
$f[i]$ 表示以 $i$ 结尾的上升子序列中的最长长度。
¶转移
$f[i] = max(f[j]) + 1$,$i < j$ 且 $a[i] < a[j]$
¶初始状态&取答案
初始状态 $f[i] = 1$
取答案 $ans = \text{max}(f[1] \dots f[n])$
For i = 1->n
{
f[i] = 1;
For j = 1->i-1
if (a[j] < a[i]) f[i] = max(f[i], f[j] + 1)
}
时间优化
可以优化成 $O(n \log n)$
用二分的方法
¶更多经典问题
- 最长公共子序列
- 最大子段和
- 最长公共上升子序列
杨辉三角
0 1 2 3 4
0 1
1 1 1
2 1 2 1
3 1 3 3 1
4 1 4 6 4 1
c[n][m] = C[n-1][m] + C[n-1][m-1];
¶背包问题
¶01 背包问题
给 $n$ 个物品,每个物品有体积 $v_i$ 以及价值 $w_i$,取 $n$ 个物品的一个子集,使得体积和不超过 $m$,并且价值和尽量大。
如果采用贪心的方法取,肯定能举出反例。
状态
$f[i][j]$ 表示考虑前 $i$ 个物品,占用体积为 $j$,能得到的最大价值。
转移
$f[i][j]=\text{max}(f[i-1][j], f[i-1][j-v[i]]+w[i])$
考虑第 $i$ 个物品取还是不取
取则从 $f[i - 1][j-v[i]]+w[i]$ 转移过来
不取则从 $f[i-1][j]$ 转移过来
空间优化
(图解)
滚动数组
数组 $f[i][j]$ 的取值只与上一行有关,开数组 $f[2][maxn]$
用 $f[i%2][j]$ 代表当前行
用 $f[(i-1)%2][j]$ 代表上一行
进一步优化
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= v[i]; j--) f[j] = max(f[j], f[j - v[i]] + w[i]);
}
从后向前更新,$j$ 以后的是当前行,$j$ 以前的是上一行。
¶完全背包
与 01 背包不同,每个物品可以不限制次数取。
转移方程略作修改
for (int i = 1; i <= n; i++)
{
for (int j = v[i]; j <= m; j++) f[j] = max(f[j], f[j-v[i]] + w[i]);
}
¶更多背包问题
- 多重背包:二进制拆分
- 混合背包:01,完全,多重背包的混合
- 二维费用背包
- 分组背包
- 背包九讲
二进制拆分图解