反悔贪心
一.什么是反悔贪心
顾名思义,反悔贪心就是两个操作:“反悔” + “贪心”。
一般来说,贪心仅能解出局部最优解。
那么在要求全局最优解时,我们就可以利用“反悔”这个操作解决。
反悔贪心的思想是:每次都进行操作,在以后有最优情况的时候再取消这次操作。
二.反悔贪心基本操作
一般来说,我们采用一个堆来存之前的贪心决策,堆顶是最劣决策。(想要让决策最优必然要撤销之前的最劣决策)
分两种情况:
-
符合某种条件时,推入堆,计算答案。
-
不符合某种条件时,与堆顶比较,做出操作。
接下来用一些例题来帮助大家理解这个算法。
三.反悔贪心例题
P3049 [USACO12MAR]Landscaping S
还有他的加强版P2748
可以算是比较板子的反悔贪心的题了。
保证
有了这句话我们就可以一盆一盆来转移泥土
我们遍历每一个节点,更新 ans,ans表示到当前节点为止前面所有节点都满足要求的最小代价。
这样我们遍历完最后一个节点后,ans便是最终答案。
对于泥土不够的,我们先花费x代价添加泥土,对于泥土过剩的,我们先花费y代价移走泥土。
同时我们要维护两个堆 q1,q2
q1 存之前的添加泥土的操作
q2 存之前的移走泥土的操作
这样我们存下这些操作便于以后撤销。
堆的比较规则我们会在下面提到。
我们考虑两个花坛之间转移的情况。
情况一:当前花坛的泥土不够
我们设当前看到第
我们来考虑转移的代价
因为我们是从之前泥土过剩的花坛中转移
所以有
因此
从
而
移走
因为我们 ans 的定义是前面所有节点都满足要求的最小代价,也就是说,此时 ans 的值是已经移走了
从
移走
不难发现,
-
该位置进行过移走泥土的操作
-
最大
堆 q2 存的是之前的移走泥土的操作,所以 q2 内的位置均满足性质一,而我们只需让 q2 维护为一个使
接下来更新 ans :
-
转移的代价更大,即
ans+=x
,并将当前操作加入 q1 -
转移的代价更小,即
ans+=z * i - (z * j + y)
,并取出 q2 的堆顶,并将当前操作加入 q1(有可能 和 转移并非最优,所以要把这次也加入 q1,方便后面撤销)
情况二:当前花坛的泥土过剩
与情况一同理
设当前看到第
我们来考虑转移的代价
因为我们是转移到之前泥土不够的花坛中
所以有
因此
从
而
移走
因为我们 ans 的定义是前面所有节点都满足要求的最小代价,也就是说,此时 ans 的值是已经补全了
从
移走
不难发现,
-
该位置进行过补全泥土的操作
-
最大
堆 q1 存的是之前的补全泥土的操作,所以 q1 内的位置均满足性质一,而我们只需让 q1 维护为一个使
接下来更新 ans :
-
转移的代价更大,即
ans+=y
,并将当前操作加入 q2 -
转移的代价更小,即
ans+=z * i - (z * j + x)
,并取出 q1 的堆顶,并将当前操作加入 q2(有可能 和 转移并非最优,所以要把这次也加入 q2,方便后面撤销)
至此我们这道题的思路就讲完了。
code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=100010;
int n,a[N],b[N],ans,x,y,z;
priority_queue<int> q2,q1;
signed main() {
cin>>n>>x>>y>>z;
for(int i=1;i<=n;i++){
cin>>a[i]>>b[i];
if(a[i]<b[i]){//情况一:当前花坛的泥土不够
for(int j=1;j<=b[i]-a[i];j++)//一盆一盆转移
if(q2.empty()||z*i-q2.top()>x){
ans+=x;
q1.push(z*i+x);
}else {
int g=q2.top();
ans+=z*i-g;
q2.pop();
q1.push(z*i+z*i-g);
}
}else if(a[i]>b[i]){//情况二:当前花坛的泥土过剩
for(int j=1;j<=a[i]-b[i];j++)//一盆一盆转移
if(q1.empty()||z*i-q1.top()>y){
ans+=y;
q2.push(z*i+y);
}else {
int g=q1.top();
ans+=z*i-g;
q1.pop();
q2.push(z*i+z*i-g);
}
}
}
cout<<ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探