状压dp
背包问题
如果要表示物品放不放:如果五个物品都不放,可以用00000表示;如果五个物品都放,可以用11111表示
可以用一个维度表示所有物品放与不放的情况,这个过程就叫做状态压缩
1 |
|
背包问题
如果要表示物品放不放:如果五个物品都不放,可以用00000表示;如果五个物品都放,可以用11111表示
可以用一个维度表示所有物品放与不放的情况,这个过程就叫做状态压缩
1 | #include<stdio.h> |
- 要求统计满足一定条件的数的数量
- 这些条件经过转化后可以使用数位的思想去理解和判断
- 输入会提供一个数字区间来作为统计的限制
- 上界很大,暴力枚举验证会超时
求a~b
中不包含49的数的个数
1 | #include <cstdio> |
求a~b
之间有多少个不含前导0且相邻两个数字之差至少为2的正整数
1 | #include<bits/stdc++.h> |
区间dp就是在***区间上进行[动态规划]***,求解一段区间上的最优解。主要是通过合并小区间的 最优解进而得出整个大区间上最优解的dp算法
核心思路
那么我把这个区间分割成一个个小区间,求解每个小区间的最优解,再合并小区间得到大区间即可
1.可以枚举区间长度len为每次分割成的小区间长度(由短到长不断合并),
2.内层枚举该长度下可以的起点。
3.然后在这个起点终点之间枚举分割点,求解这段小区间在某个分割点下的最优解
4.写出特定的状态转移方程(重点)
板子
1 | for(int len = 1;len<=n;len++){//枚举长度 |
四边形不等式优化
1.区间包含的单调性:如果对于i≤i’<j≤j’,有 cost(i’,j)≤cost(i,j’),那么说明 cost 具有区间包含的单调性。(可以形象理解为如果小区间包含于大区间中,那么小区间的cost值不超过大区间的cost值 ),证明可通过题目定义的cost(i,j)的含义进行论证
2、四边形不等式:如果对于i≤i’<j≤j’,有 cost(i,j)+cost(i’,j’)≤cost(i’,j)+cost(i,j’),我们称函数 cost 满足四边 形不等式。(可以形象理解为两个交错区间的cost的和不超过小区间与大区间的cost的和——(交叉小于包含))
两个定理:
1、如果上述的cost 函数同时满足区间包含单调性和四边形不等式性质,那么函数 dp也满足四边形不等式性质 我们再定义s(i,j)表示dp(i,j) 取得最优值时对应的下标k(即 i≤k≤j 时,k 处的 dp 值最最优,则 s(i,j)=k)。此时有如下定理:
2、假如 dp(i,j) 满足四边形不等式,那么 s(i,j)(自变量为i、j两个变量) 单调,即s(i,j)≤s(i,j+1)≤s(i+1,j+1)
即原来的状态转移方程
可以改写为下式:dp(i,j)=min{dp(i,k-1),dp(k,j)}+cost(i,j)(s(i,j-1)≤k≤s(i+1,j))
1 | for(int len=2;len<=n;len++) { //枚举长度 |
1 | #include <bits/stdc++.h> |
1 | #include <cstdio> |
1 | #include <bits/stdc++.h> |