wqs二分(带权二分)总结

wqs二分一般用于解决这样一种问题:
dp是凸函数,也就是多选一个物品,收获肯定更多
这种问题一般是有限制的,比如限制最多选择m个物品
且如果没有限制,将很容易计算
f u f_u fu表示选 u 个的收获,图像如下:
wqs二分(带权二分)总结_第1张图片我们要找到这样一个 ( m , f m ) (m,f_m) (m,fm)
可以二分斜率 k ,得到斜率 k 的直线与图像相切的点,这个点相当于是截距最大的点,截距 g u = f u − k ∗ u g_u=f_u-k*u gu=fuku,相当于每个物品都减少 k 的价值,得到的最大的贡献点对应的x坐标,如果x大了意味着斜率小了,否则说明斜率大了,这样就能求出 f m f_m fm

P2619 [国家集训队]Tree I

f i f_i fi表示至少有i个白边的最小生成树的权值
那么 f i f_i fi一定是单调不减,可以给每个白边加一个值做最小生成树,二分这个值即可

代码

CF739E Gosha is hunting

wqs二分套wqs二分
对两个维度分别二分,每次验证的时候进行一次dp,总时间复杂度 O ( n l o g 2 n ) O(nlog^2n) O(nlog2n)
代码
这题还可以费用流,4000个点也不知道怎么跑过的

P4383 [八省联考 2018] 林克卡特树

考虑时间复杂度 O ( n k ) O(nk) O(nk)的树形dp
f [ u ] [ j ] [ 0 / 1 / 2 ] f[u][j][0/1/2] f[u][j][0/1/2]表示dp到u节点,用了k个链,u节点使用的度数为0/1/2的最大值
那么我们很容易得到转移,60pts

容易发现k越大肯定会得到不劣的答案,所以可以使用wqs二分来优化
每次使用一个链就减去一个mid值,看看最大化答案需要的链的数量,如果大于要求的说明斜率mid小了,否则就是mid大了,可以二分解决

注意dp的时候维护的细节即可
代码

你可能感兴趣的:(wqs二分,带权二分,算法)