一、知识点整理
(一)、动态规划是解决多阶段策略问题的一种方法,运用最优性原理,排除重复计算,用空间换时间的算法。
(二)、动态规划适用的题目类型有以下几个特点:
1.问题具有多阶段的决策
2.每个阶段对应一个状态(状态变量)
3.每个阶段有一个决策(不同的决策导致下一个阶段不同的状态)
4.每个阶段的最优解可以递归地归结为下一个阶段各个可能状态的最优解问题
(三)、一般的解题步骤
1.判断问题是否具最优子结构性质者
2.分阶段
3.建立状态转移方程(递归公式)
4.找出边界条件
5.将已知的边界值带入方程
6.递归求解
(四)、背包问题
1、01背包
特点:每种物品仅有一件,可以选择放或不放,求最大价值
状态转移方程:f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]};
伪代码:(空间优化)
for i=1..N
for v=v..0
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
(若要求恰好装满背包,初始化的时候除了将f0]=0,其余的均为负无穷;
若没有要求必须装满,初始化的时候将f[0...v]都设成0)
2、完全背包
特点:每种物品有N件,可以用无限次,求费用总和不超过容量的最大价值
状态转移方程:f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i](0<=k<=v/c[j]);
伪代码:(空间优化)
for i..N
for v=0..V
f[v]=max{f[v],f[v-cost[i]]+w[i]}
(简单优化:将费用大于容量的去掉,两个物品相比,若一个的费用高并且重量小则直接去掉)
3、多重背包
特点: N种物品和容量为V的背包,第i种物品最多有n[i]件可用,求费用总和不超过容量的最大价值
优化:
二进制思想:多重背包中的一个物品变成0-1背包中的多个物品
4、分组背包
特点:N件物品容量为V,这些物品被分若干组,每组中的物品发生冲突时最多选一件。转化为每组物品有若干种策略
状态转移方程:f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i](物品i属于k组)
伪代码:
for k=1..K(所有k组)
for v=V..0
for 所有的i属于k组
f[v]=max{f[v],f[v-c[i]+w[i]]}
5、区间DP
区间动态一般都是将一个区间问题不断划分为更小的区间甚至一个元素组成的区间,枚举他们的组合,求合并后的最优值。
区间动态规划的模板代码:
for(int p=1;p<=n;p++){
for (inti=1;i<=n;i++){
int j=i+p-1;
for (int k=i;k<j;k++)
dp[i][j]=min{dp[i][k]+dp[k+1][j]+w[i][j]};
dp[i][j]=max{dp[i][k]+dp[k+1][j]+w[i][j];
}}
二、感悟
老师刚开始上课就说,这部分题简单的很简单,难得很难,确实体会到了。刚开始做的那几个题,太简单了,代码分分钟写出来AC,但是做到后边。。。
有些题目动态规划和贪心算法都能解决,但是不同的是,动态规划的下一步状态与前一步密切相关。最难的地方就是状态转移方程,刚开始做直接晕了,非常不理解,后来做的多了,慢慢的就有点懂了,但是主要还是靠套公式,感觉还是没有真正理解。
这个专题老师延长了很长时间,但还是没有做完题目,而且最后几篇博客都是刚补的,还是应该做一个题写一篇博客,否则时间长了思路都忘了。下个专题得改掉这个不好的习惯。