反悔贪心
算法思想
反悔贪心算法(Regret-Greedy Algorithm)是一种特殊的贪心算法变种,主要应用在需要多次决策的优化问题中。它的核心思想是允许在某些情况下撤销之前的决策(即“反悔”),并做出更优的选择,从而提高整体解的质量。
算法流程
- 初始贪心决策:首先按照普通的贪心策略做出一系列初步决策,每次都选择当前最优解。
- 反悔检查:在每次决策之后,检查当前的选择是否与后续的决策产生冲突或者是否有更好的选择可以替代之前的决策。
- 反悔操作:如果发现某个决策不是最优的,或者对后续决策产生了负面影响,可以撤销该决策,重新选择更优的决策。
- 重复反悔过程:不断重复上述过程,直到不再需要反悔操作,即当前的所有决策都达到局部最优。
例题
您可以完美预测某只股票未来 N 天的价格。每天你要么买入一股,要么卖出一股,要么什么都不做。起初你拥有零股,当你没有任何股票时,你不能卖出股票。在 N 天结束时,您希望再次拥有零股,但希望拥有尽可能多的资金。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
priority_queue<int, vector<int>, greater<>> pq;
long long ans = 0;
while(n--){
int x;
cin >> x;
if(not empty(pq) and pq.top()<x){
ans+=x-pq.top();
pq.pop();
pq.push(x);
}
pq.push(x);
}
cout << ans << endl;
return 0;
}
故障机器人共有 x 点生命值,他在高塔中遭遇了 n 个敌人,在和第 i 个敌人战斗后故障机器人会损失 ai 点生命值,在战斗结束后生命值降低到 0 或以下时故障机器人会死亡。同时,故障机器人手上有 k 个烟雾弹,在战斗开始时,他可以选择消耗 1 个烟雾弹来逃离这场战斗,如此战斗会直接结束,故障机器人在这场战斗中不会损失生命值。
故障机器人将依次与 n 个敌人进行战斗,他想知道在最优策略下,最多能存活到第几场战斗结束,你能帮帮故障机器人吗?
#include <bits/stdc++.h>
using namespace std;
int main(){
int task;
cin>>task;
while(task--){
int n,x,k;
cin>>n>>x>>k;
vector<int> v(n);
for(int &x:v)cin>>x;
priority_queue<int,vector<int>,greater<>> pq;
int i;
for(i=0;i<n;i++){
if(size(pq)<k){
pq.push(v[i]);
continue;
}
pq.push(v[i]);
if(pq.top()>=x)break;
x-=pq.top();
pq.pop();
}
cout<<i<<endl;
}
}