动态规划
性质:
1.最优子结构
2.无后效性:能够拓扑排序;
状态转移
初始状态和边界很重要
方便转移状态。
滚动数组
1.逆向:每个状态只会更新一次
顺向:每个状态更新多次,说明可以用多次
序列型dp
最长上升子序列
区间型dp
石子合并*能量项链*
洛谷:p1622
把编号作为阶段,因为每个名单上的都要释放
启发:把必须要完成的事分阶段
格式:模板
//表示从左端点一点点扩大区间并向右移动
for(int i=1;i<=m;i++)
for(int j=i+1;j<=m;j++)
//表示固定一个区间长度,并不断扩大右移
for (int l = 1; l <= m; l ++)
for (int i = 1; i + l - 1 <= m; i ++)
{
int j = i + l - 1;
//正解
//1.dp含义
f[M][M]; // f[i][j] 表示把 编号在 [i,j] 内的罪犯放掉所需要的最少送肉量
//2. 初始化,边界
sort(P + 1, P + m + 1);
P[m + 1] = n + 1;//dp方程中,计算长度要用p【j+1】所以把m+1记为n+1;//3.子问题解决
for (int l = 1; l <= m; l ++)//第l个罪犯
for (int i = 1; i + l - 1 <= m; i ++)
{
int j = i + l - 1;
f[i][j] = INF;、、初始化
for (int k = i; k <= j; k ++) // 枚举在编号在 [i,j] 内第一个被释放的罪犯
f[i][j] = min(f[i][j], f[i][k - 1] + f[k + 1][j] + (P[j + 1] - P[i - 1] - 2));
}//4.答案位置
printf("%d\n", f[1][m]);
”四边形不等式“传送门
空间型dp
洛谷p1373
适当增加维度来适应题目的要求
初始dp:f[i][j]=f[i-1][j]+f[i][j-]
- 加上取模
- 加上魔法差
- 加上两个人
- 加上魔法值会超过k+1即减为1而非纯粹加。
5.从任意起点,任意终点
所以实现上与基础空间dp有所不同
- #define mod 10000007
- 加维度f[i][j][k][2],走到i,j,魔法值差为k,0为小a,1为uim、
- int last_l = (s ? k - 1 : 1) * A[i][j] % k+ l,)% k;
- f[i][j][A[i][j]][1] = Inc(f[i][j][A[i][j]][1], 1);
ans = Inc(ans, f[i][j][0][0]);
写在i,j循环内。
p.s:dp方程的表示意义
树形dp
子树型
1.洛谷p1122最大子树
要点:
扫描二维码关注公众号,回复:
2408346 查看本文章
- 连双向边
- *初始状态:*f[i]=v[i];表示当前子树只有自己一个
- 初始化:ans=-无穷
- 用dfs自下而上f[x]加上非负的子树。负的显然不是最优
- f[x]更ans之间取max
链型
更新完全部子树再更新父亲节点
自底向上更新。
数位型dp
- 拆分范围
- 状态f[n][k][2].
- 两种情况:【0】0—9,【1】j==w【i-1]时j+o—w【i-1】
- 边界 :f【1】【】【】
- ans=f【】【】【0】+f【】【】【1】;
状态压缩dp
1.找到关键状态.
2.位运算。
DAG上动态规划
Dp优化,慢慢理解
矩阵快速幂
- 满足结合律
- 把转移式变为矩阵形式
- o(tnm^2)->o(m^3logt)
- 实现形式:
前缀优化
简单数据结构优化
- ps:线段树,树状数组优化最长上升子序列
- 堆,优先队列(单调队列)。
- 例题:洛谷p3572
离散优化
斜率优化 ##较难
- (单调队列拓展)
- 推理过程……
- 代码实现: