[笔记] 带悔贪心
简介
贪心的局限性在于其只满足当前的最优,无法保证全局的最优,一般此时就会选择 DP ,但是有的情况,可以通过加入“反悔”操作来保证正确性。
同时,带悔贪心又名模拟费用流,原因是有的问题可以使用费用流解决,但是费用流的复杂度过高,由于图的特殊性,分析出可以带悔贪心。
同时,有些较为复杂的带悔贪心题目也许可以使用 wqs 二分以时间多一个 \(\log\) 的代价解决。
题目
P1792 [国家集训队]种树
选了位置 \(x\),若反悔,肯定是选上两边 (因为反悔,有些位置逐渐绑定在一起,两边的概念在变化)
lfor(i, 1, m){
while(ban[Q.top().se]) Q.pop();
int x = Q.top().se; Ans += Q.top().fi, Q.pop();
ban[l[x]] = ban[r[x]] = 1;
a[x] = a[l[x]] + a[r[x]] - a[x], Q.push({a[x], x});
l[x] = l[l[x]], r[x] = r[r[x]];
r[l[x]] = x, l[r[x]] = x;
}
YZOJ4977 跳伞求生
选了 \(a_i\) 去 \(b_j\) 房间,如果反悔,一定是更优的 \(a_k\) 无处可去了,替换后增长的是 \(a_k-a_i\)
for(int i = 1, j = 1; i <= n; ++i){
while(j <= m && b[j].fi < a[i]) Q.push(-b[j].fi + b[j].se), ++j;
if(!Q.empty() && a[i] + Q.top() > 0)
Ans += a[i] + Q.top(), Q.pop(), Q.push(-a[i]);
}