2025国庆dp
经典例题
设fi表示i这个时刻发车最小答案,枚举上一次发车的时间j,容易转移
但这是O(t^2)
考虑优化
1.斜率优化
2.发现n,m<t,设计fi这种状态很浪费
优化1:若两次发车间隔>2m,完全可以再发一辆车,于是复杂度O(tm)
优化2:若某次发车之前的m个时刻内都没有人,这个点是废点,只会用作优化1,于是直接fi=fi-m转移
最终复杂度O(T+n*m^2)
3.更改dp状态
gi,j表示运走了前i个人,第i个人的等待时间为j
则ti + j就是第i个人接走的发车时间
考虑分段的经典思路:i和i-1是否同一辆车
简单转移
其中不在同一辆车可以前缀min优化
复杂度O(nm)
是否还可以继续优化?
考虑对人做分段
而不是对时间分段
考虑每次发车,要不就是在有人来的时间点发车,或者上一个人发车结束后紧接着发车
预处理后一种情况,枚举上一个发车的点
复杂度O(min{nn,nm})
dp=观察性质+搜索+状态优化+转移优化
树形DP
设fu,i,j表示u到根,i条L边,j条R边未被指定
枚举左右儿子指定哪条边即可
答案是f[1][0][0]
初始化所有叶子
对每条边算贡献
树上背包
数位DP
需要记录是否顶着上界,是否处于前导0
发现dfs可以很好的解决这个问题
板子
把要求的答案转化成对每种sum(i)求恰好有sum(i)个1的数的个数
答案即为i^(个数)最后乘起来即可
这就显然可以数位dp了
dpi,j,k表示填到第i位,数位lcm为j,得到的数%j=k的方案数
发现状态过大开不下
发现lcm(1,2,3,4,5,6,7,8,9)=2520
而2520的因子只有48个
容易发现数位lcm一定是2520的因子
于是第二维只用开48
对应存值即可
状压DP
位运算小技巧
1.枚举子集:
for(int i=S;i;i=(i-1)&S){
//i in S
}
2.提取第i位:S>>i&1
3.改变第i位:S^=1<<i
4.提取最后一位1及其后面的0:S&(-S)
压空间小技巧:折半计算二进制答案
例如:取log,当大于2^(n/2)时
答案为a[x/(2^(n/2))]+n/2
例题:
首先发现O(n!*n)很好写
全排每种情况,check时贪心
考虑将这个东西转成dp
dpS,i,j,k表示操作完的集合为S,最后一个选的b为i,sum(b)=j,最后一个选的位置是k
发现对于目前最后一个选的数b,满足的性质是形如 b - (a_i-a_(i-1)) > 0的东西
贪心选最小则b=a_i-a_(i-1)
于是去掉i这一维,发现这一个b的加入对后续的影响为 (a_i-a_(i-1))*(n-i+1)
容易转移
时间复杂度O(2n*n2*m)
选择的一定是一棵树
dpS,i表示选了S的关键点,根为i
转移分两部分,一部分是树上所有点度数<=1,第二部分是将树拆成若干满足图上所有点的度数<=1的图
dpS,i+wi,j=>dpS,j
dpS,i+dpSS,i=>dpS+SS,i
第二部分直接求即可
第一部分发现是最短路
发现ans一定<=3n
(可以先将B数组清0,对每个A中1的位置,对B修改并复原)
接下来就需要观察性质

浙公网安备 33010602011771号