被数据结构暴虐十几天,苟延残喘的我终于开始了dp进阶
首先来复习复习基础
动态规划:Desperate Dynamic Programming
dp的思想基础:问题的可划分性和子问题的相似性
个人理解:用子问题的解组合成原问题的解
小说dp的三要素:阶段,状态,决策
使用dp的三前提:
- 子问题重叠性
- 无后效性
- 最优子结构性
线性dp
Mr Youngs Picture Permutations(luogu)
观察性质发现符合条件的方案中
对于每一列不可能行数大的有数而行数小的没数,对于每一行不可能列数大的有数而列数小的没数
于是可以设计阶段:当前要把 i 这个数放入并且 i 之前的数都已经放入
状态:每一行放了多少个数
决策:尝试把 i 放到各行中累计方案数
阶段:匹配到ai(不一定为LCIS的一部分 )
状态:匹配到bj(一定为LCIS的末尾)
于是设f [ i ][ j ](i , j 意义同上)表示LCIS的长度
决策:f[ i ][ j ]= f [ i-1 ][ j ] ( ai != bj )
max(f [ i-1 ][ k ])+1 0<=k<j,bk<ai ( ai == bj )
并利用决策集合大小的单调递增性优化复杂度
它为什么是蓝色的...
发现数据范围很大,考虑特殊性质
发现利用数学归纳法证出bi必为a中一个数
阶段:完成 i 个数的构造
状态:最后一个数为 j(离散后)
决策:枚举符合条件的前一个数的值更新当前问题答案
背包
01背包
完全背包
多重背包:
二进制拆分(好东西)
假设某个物品有3个,则向背包中+1+2=+3,增加了复杂度
考虑找到一种方法可以表示一定范围内的每个数,联想到二进制
对于一个数c,设p为最大的2^0+2^1+..+2^p<=c,r=c-2^p-...-2^0,
则r , 2^0 , 2^1....2^p中取若干数相加可得到1~c中每个数
分组背包