系统性动态规划分类总结(二):遍历顺序
本系统性总结分两篇,看这一篇之前可以先阅读第一篇内容
系统性动态规划分类总结(一):dp数组定义与递推公式
前言
- 动态规划的遍历循环通常是双层,通过[系统性动态规划分类总结:dp数组定义与递推公式] 一节可以知道,通常有两个变量,容器容积和填充元素。
- 那么遍历顺序这一节就会牵扯到两个问题
- 一个是哪个是内层循环,哪个作为外层循环,
- 第二个就是倒序遍历还是正序遍历。
- 如果递推公式中包含了明确的大小关系,那么就不用思考了,比如如下情况:(注意,这种dp矩阵维度和遍历维度必须一致)
- 如果确定的dp矩阵是这样的,
dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]) - 因为dp是2维,遍历也是2维(
i,j两个循环变量值),那么就不用思考其他了,因为dp[i][j]的值依赖于dp[i-1][j]和dp[i-1][j-weight[i]] - 那么肯定就是都是正序,因为要先将后面两个算完才能算
dp[i][j] - 那么顺序也就不用管了,怎么来都行,只要将整个算完就好。
- 当然,如果没有这种关系,那就要看下面的内容来确定。
- 如果确定的dp矩阵是这样的,
情况分类
每个元素无限次选取。
- 通常是枚举选哪个问题,就是将枚举值往容器中填。
- 所以这个就很好理解,外层循环是遍历容器,内层循环是遍历枚举值。
- 因为大容积容器值通过小容积容器计算,所以外层通常是正序遍历,
- 内层遍历枚举值,所以正反序没有影响。
每个元素只能选一次。
- 这种情况不能通过上述方式,将元素往容器中填,因为会牵扯到重复的问题。
- 因为在里层循环明显会被多次遍历获取。所以一定是遍历元素是外层,遍历容器是内层。
- 那么正反序遍历需不需要考虑——一定是要考虑的,这种考虑需要看递推公式。
- 假设某题递推公式为
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);weight[i] > 0 - 那么我们知道
dp[j]依赖于dp[j-weight[i]], 也就是下标大的依赖于下标小的。这种情况下,如果我们正序,那么就是外层的物品就会被考虑多次,就会变成重复的了。
用代码来理解,我们使用上一节说的

:遍历顺序&spm=1001.2101.3001.5002&articleId=139073204&d=1&t=3&u=1e9b4a3bf70b4695973fb9d8b55bd22b)
1462

被折叠的 条评论
为什么被折叠?



