今天老师口胡了一波动归,如果有其他人发了一篇差不多的,一定是我同学!
动态规划:
范围:适于解决多阶段、多决策、最优解(求方法数)问题
与贪心、分治的对比:
贪心 :
当前阶段 ,选最优(每次选取能取到的最优值,从而得到一个局部最优值) 。例题:潜水
分治:
分而治之 ,也就是分->治
例题(或用法):快排 ,归并排序
动态规划:
当前阶段, 记录 所有的最优 (也就是常说的空间换时间)
由于分部分的时候,重合部分经常出现,就会出现大量重复的递归调用,然而用了记忆化搜索来解决,可使动归 进一步 转换为递推。
动态规划的两个必要条件:
1)无后效性:当前的最优解与后面无关;
2)最优子结构:每次都要保证最有值;
看到这两个条件满足就基本确定是动态规划了;
动归解题步骤:
1)确定能用动态规划解决;
2)划分阶段:时间,空间,顺序;(不同阶段效率不同,具体题目具体分析)
拓扑排序*也是阶段划分
floyd 的k循环
3)设置状态:前i阶段的xxxxxx的最优值是什么
设置f[i]([j]),表示某个状态的最优值
洛谷 2519,为海亮题库(HLOJ)407加强版;
状态是几维,循环也就是几重循环
区间类:从第i个到第j个的最优值;
4)建立状态转移方程
当前的状态(最优值、方案数)有前面那些状态推导出;
继续加循环;
例:零一背包:
f[i][j]状态表示 前i个物品占据容量为j的背包的最优值
故转移方程为
f[i][j]=max(f[i-1][j](0,即不取),f[i-1][j-w[i]]+v[i](1,表示取));
*拓扑排序定义:拓扑排序顺序就是在图上做动态规划的阶段划分;(满足条件时)
动态规划的分类:
动态规划分类的最终目的,是不分类。
1) 资源分配
HLOJ411机械分配: f[i][j] 状态表示前i个公司 分配 j 台机器
412马棚:状态:前i匹马分j个马棚
使用三重循环实现;
延伸:输出方案,是noip里也会考察的
2) 背包
a ) 0/1 背包:
f[i][j]= max(f[i-1][j],f[i-1][j-c[i]]+w[i])
不要 要第i个物品
用一维实现状态 : f[j] i循环(v...c[i]) 倒着循环;
PS:零一背包是其他所有背包类问题及变形的基础,所以一定要掌握,详见背包九讲(https://wenku.baidu.com/view/5e9062717fd5360cba1adb37.html)
b)完全背包
f[i][j]= max(f[i-1][j],f[i][j-c[i]]+w[i])
不要 要第i个物品
一维状态 : f[j] i循环(c[i]...v) 正着循环;
PS:观察零一背包与完全背包二维状态、一维状态的分别不同之处并思考原因。
c)多重背包
每个物品有多个,第i个物品有k个, 1倍,2倍,3倍……k倍
二进制优化 Log2(k)
13= 1 12
2 10
4 6
6
d)二维体积背包
f[i][j][k]设置三维的状态,其实与零一没什么区别,只要再加上一层循环而已,转移方程也类似
同时也可以压缩为二维的:
f[j][k]=max(f[j][k],f[j-w1[i]][k-w2[i]]+v[i]);
e)分组:
可以将每组都合并成一个物品,再按照零一来做;
f)有依赖 (树形动态规划):
这个。。。已经不在今天的范围之内了。。。
若是想学习还是另请高明吧。
PS:背包类问题是动态规划的重点考点,熟悉掌握才能应对考场上的各种变形、结合的背包问题。
3) 双进程:
两个进程,用i、j分别指示;通过两个进程之间的关系来求解;
具体的可以自行百度;
例题:最长公共子序列、构建双塔等;
4) 区间类
区间问题的状态设置、转移方程都不同于其他的dp,
f[i][j]表示从第i个 到 第 j个 的最优值
f[i][j];
阶段 : 区间长度
for (int p=0;p<=n;p++) //区间长度
for (int i=1;i<=n;i++)//起点位置
{
int j=i+p;//终点
if (j>n) break;//还可以这样。。。。
求 f[i][j]
}
环状的区间类: 长度变两倍,依次去做
5) 二维 由线性变成了平面
呵呵,我还没学呢;
例题:农田个数、创意吃鱼;
听说都是有意思的题;
----------------------------------------------------------------------------------------------------------------------------
呼,就是这样,刘老师口胡一波的东西我加了一些改动就放上来了。。。。