首页 > 其他分享 >反悔贪心

反悔贪心

时间:2022-10-06 14:34:11浏览次数:75  
标签:q1 cdot 花坛 反悔 泥土 ans 代价 贪心

一.什么是反悔贪心

顾名思义,反悔贪心就是两个操作:“反悔” + “贪心”

一般来说,贪心仅能解出局部最优解。

那么在要求全局最优解时,我们就可以利用“反悔”这个操作解决。

反悔贪心的思想是:每次都进行操作,在以后有最优情况的时候再取消这次操作。

二.反悔贪心基本操作

一般来说,我们采用一个堆来存之前的贪心决策,堆顶是最劣决策。(想要让决策最优必然要撤销之前的最劣决策)

分两种情况:

  1. 符合某种条件时,推入堆,计算答案。

  2. 不符合某种条件时,与堆顶比较,做出操作。

接下来用一些例题来帮助大家理解这个算法。

三.反悔贪心例题

P3049 [USACO12MAR]Landscaping S

还有他的加强版P2748

可以算是比较板子的反悔贪心的题了。

保证 $0 \leq A_i,B_i \leq 10≤A $

有了这句话我们就可以一盆一盆来转移泥土

我们遍历每一个节点,更新 ans,ans表示到当前节点为止前面所有节点都满足要求的最小代价。

这样我们遍历完最后一个节点后,ans便是最终答案。

对于泥土不够的,我们先花费x代价添加泥土,对于泥土过剩的,我们先花费y代价移走泥土。

同时我们要维护两个堆 q1,q2

q1 存之前的添加泥土的操作

q2 存之前的移走泥土的操作

这样我们存下这些操作便于以后撤销。

堆的比较规则我们会在下面提到。

我们考虑两个花坛之间转移的情况。

情况一:当前花坛的泥土不够

我们设当前看到第 \(i\) 个花坛,并且第 \(i\) 个花坛泥土不够,我们除了选择补全泥土以外,还可以选择从之前泥土过剩的花坛中转移,所以我们要比较 从 \(j\) 花坛转移泥土至 \(i\) 花坛移走 \(j\) 花坛泥土且补全 \(i\) 花坛泥土 两种决策哪个代价更小,我们要选取其中的代价小的作为最优决策。

我们来考虑转移的代价

因为我们是从之前泥土过剩的花坛中转移

所以有 \(j<i\)

因此

从 \(j\) 花坛转移泥土至 \(i\) 花坛花费代价: \(z \cdot (i-j)\)

移走 \(j\) 花坛泥土且补全 \(i\) 花坛泥土花费代价:\(x+y\)

因为我们 ans 的定义是前面所有节点都满足要求的最小代价,也就是说,此时 ans 的值是已经移走了 \(j\) 花坛泥土的代价,所以这两种决策对 ans 的贡献分别为:

从 \(j\) 花坛转移泥土至 \(i\) 花坛对ans的贡献: \(z \cdot (i-j)-y=z \cdot i-(z \cdot j + y)\)

移走 \(j\) 花坛泥土且补全 \(i\) 花坛泥土对 ans 的贡献:\(x\)

不难发现,\(z \cdot i\) 是定值,想要让转移的代价最小,我们要找到一个位置 \(j\) 满足:

  1. 该位置进行过移走泥土的操作

  2. \(z \cdot j + y\) 最大

堆 q2 存的是之前的移走泥土的操作,所以 q2 内的位置均满足性质一,而我们只需让 q2 维护为一个使 \(z \cdot j + y\) 最大的大顶堆,这样我们每次取堆顶就是我们需要的位置 \(j\)。

接下来更新 ans :

  • 转移的代价更大,即 \(z \cdot i-(z \cdot j + y) >= x\)

    ans+=x,并将当前操作加入 q1

  • 转移的代价更小,即 \(z \cdot i-(z \cdot j + y) < x\)

    ans+=z * i - (z * j + y),并取出 q2 的堆顶,并将当前操作加入 q1(有可能 \(i\) 和 \(j\) 转移并非最优,所以要把这次也加入 q1,方便后面撤销)

情况二:当前花坛的泥土过剩

与情况一同理

设当前看到第 \(i\) 个花坛,并且第 \(i\) 个花坛泥土过剩,我们除了选择移走泥土以外,还可以选择转移到之前泥土不够的花坛中,所以我们要比较 从 \(i\) 花坛转移泥土至 \(j\) 花坛移走 \(i\) 花坛泥土且补全 \(j\) 花坛泥土 两种决策哪个代价更小,我们要选取其中的代价小的作为最优决策。

我们来考虑转移的代价

因为我们是转移到之前泥土不够的花坛中

所以有 \(j<i\)

因此

从 \(i\) 花坛转移泥土至 \(j\) 花坛花费代价: \(z \cdot (i-j)\)

移走 \(i\) 花坛泥土且补全 \(j\) 花坛泥土花费代价:\(x+y\)

因为我们 ans 的定义是前面所有节点都满足要求的最小代价,也就是说,此时 ans 的值是已经补全了 \(j\) 花坛泥土的代价,所以这两种决策对 ans 的贡献分别为:

从 \(i\) 花坛转移泥土至 \(j\) 花坛对ans的贡献: \(z \cdot (i-j)-x=z \cdot i-(z \cdot j + x)\)

移走 \(i\) 花坛泥土且补全 \(j\) 花坛泥土对 ans 的贡献:\(y\)

不难发现,\(z \cdot i\) 是定值,想要让转移的代价最小,我们要找到一个位置 \(j\) 满足:

  1. 该位置进行过补全泥土的操作

  2. \(z \cdot j + x\) 最大

堆 q1 存的是之前的补全泥土的操作,所以 q1 内的位置均满足性质一,而我们只需让 q1 维护为一个使 \(z \cdot j + x\) 最大的大顶堆,这样我们每次取堆顶就是我们需要的位置 \(j\)。

接下来更新 ans :

  • 转移的代价更大,即 \(z \cdot i-(z \cdot j + x) >= y\)

    ans+=y,并将当前操作加入 q2

  • 转移的代价更小,即 \(z \cdot i-(z \cdot j + x) < y\)

    ans+=z * i - (z * j + x),并取出 q1 的堆顶,并将当前操作加入 q2(有可能 \(i\) 和 \(j\) 转移并非最优,所以要把这次也加入 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;
}

标签:q1,cdot,花坛,反悔,泥土,ans,代价,贪心
From: https://www.cnblogs.com/ycw123/p/16757567.html

相关文章

  • POJ 2227 The Wedding Juicer(三维接雨水 BFS 贪心
    POJ2227TheWeddingJuicer(三维接雨水BFS贪心)题意:​ 给出一个二维地图,其各点上权值为其高度。如果向其中填水,请问在这张地图中可以积得多少水。​ 地图长宽为300,高......
  • LeetCode 12 - 贪心
    455.分发饼干对每个孩子i,都有一个胃口值 g[i],这是能让孩子们满足胃口的饼干的最小尺寸;并且每块饼干j,都有一个尺寸s[j] 。如果s[j] >=g[i],我们可以将这个饼干j......
  • HDU-5380 Travel with candy(贪心+单调队列)
    TravelwithcandyTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:262144/262144K(Java/Others)TotalSubmission(s):396    AcceptedSubmission(s)......
  • [Oracle] LeetCode 53 Maximum Subarray 贪心
    Givenanintegerarraynums,findthecontiguoussubarray(containingatleastonenumber)whichhasthelargestsumandreturnitssum.Asubarrayisacontig......
  • 贪心算法
    应用实例假设存在如下表的需要付费的广播台,以及广播台信号可以覆盖的地区。如何选择最少的广播台,让所有的地区都可以接收到信号思路分析目前并没有算法可以快速计算得到准......
  • Leetcode 680 -- 双指针&贪心
    题目描述验证回文串思路代码classSolution{public:boolpalindrome(string&s,inti,intj){for(;i<j&&s[i]==s[j];++i,--j);......
  • *Codeforces Round #235 (Div. 2) C. Team(贪心)
    https://codeforces.com/contest/401/problem/C题目大意:给定n个0,m个1;让我们构建出一个字符串满足:不能连续2个以上的0,不能出现3个连续的1;可以的话就输出任意正确的结......
  • 贪心算法
    应用实例假设存在如下表的需要付费的广播台,以及广播台信号可以覆盖的地区。如何选择最少的广播台,让所有的地区都可以接收到信号思路分析目前并没有算法可以快速......
  • Meeting on the Line(贪心,二分,三分)
    MeetingontheLine(贪心算法)(二分,三分)题目大意:类似(实数版)货仓选址,给你n个位置(不用再这n个位置中选,可以任意选实数),再给你这n个位置出发的准备时间(可以转化成距离来看),求一......
  • 算法设计与分析课-实验-贪心
    算法设计与分析课贪心算法第一题最小延迟调度:贪心算法的基本思想:贪心算法的基本思想为从整体中找到每个小局部的最优解,并将所有局部最优解合并成整体的最优解。能够......