题意

给\(2n\)个物品,分别有\(a,b\)属性,对于\(i=1...n\),选择\(i\)个\(a\)属性和\(i\)个\(b\)属性,且每个物品只能作为一种属性的贡献,求最小的值。

分析

  • 看了题解补了两天... 应该叫做可反悔的贪心,或者其实就是网络流?不过因为是特殊的图,所以可以用优先队列来优化。
  • 维护四个优先队列,分别是未使用的\(a\)属性,未使用的\(b\)属性,已使用的\(a\)属性转化为\(b\)属性的花费,已使用的\(b\)属性转化为\(a\)属性的花费。
  • 对一般情况,每次取出最小\(a\)属性,取出最小\(b\)属性转化为\(a\)属性的花费,以及最小的\(b\)属性,判断哪种策略更优,对\(b\)属性同理。
  • 很多细节需要注意
    • 相同属性值,选择后反悔成另一种属性的花费更小的优先(无需绝对值)。比如(3,2)比(3,4)优先。
    • 两种策略的花费相同时,选择直接取出的策略,因为另一种策略需要从另一种最小堆中取出一个元素,使得堆顶元素变大。
    • 在前两个最小堆中取元素时需要判断取出元素是否已访问过。
    • 进行反悔的元素需要将花费取反然后放到另一个反悔队列里面去。

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+50;
struct node{
int id;
ll val,sec;
bool operator <(const node& rhs)const{
if(val!=rhs.val){
return val>rhs.val;
}else{
return sec-val>rhs.sec-rhs.val;
}
}
};
priority_queue<node> lc,dn,ltd,dtl;
int n,vis[N];
ll l[N],d[N];
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=2*n;i++){
scanf("%lld%lld",&l[i],&d[i]);
lc.push(node{i,l[i],d[i]});
dn.push(node{i,d[i],l[i]});
}
ll ans=0;
for(int i=1;i<=n;i++){
while(!lc.empty() && vis[lc.top().id]){
lc.pop();
}
if(lc.empty()){
auto t=dtl.top();
dtl.pop();
ans+=t.val;
auto g=dn.top();
dn.pop();
ans+=g.val;
ltd.push(node{t.id,d[t.id]-l[t.id]});
dtl.push(node{g.id,l[g.id]-d[g.id],0});
}else{
auto a=lc.top();
while(vis[a.id]){
lc.pop();
a=lc.top();
}
while(!dn.empty() && vis[dn.top().id]){
dn.pop();
}
if(dtl.empty() || dn.empty()){
ans+=a.val;
lc.pop();
vis[a.id]=1;
ltd.push(node{a.id,d[a.id]-l[a.id],0});
}else{
auto b=dtl.top();
auto c=dn.top();
if(a.val<=b.val+c.val){
ans+=a.val;
lc.pop();
vis[a.id]=1;
ltd.push(node{a.id,d[a.id]-l[a.id],0});
}else{
ans+=b.val+c.val;
dtl.pop();
dn.pop();
vis[c.id]=1;
ltd.push(node{b.id,d[b.id]-l[b.id],0});
dtl.push(node{c.id,l[c.id]-d[c.id],0});
}
}
}
while(!dn.empty() && vis[dn.top().id]){
dn.pop();
}
if(dn.empty()){
auto t=ltd.top();
ltd.pop();
ans+=t.val;
auto g=lc.top();
lc.pop();
ans+=g.val;
dtl.push(node{t.id,l[t.id]-d[t.id],0});
ltd.push(node{g.id,d[g.id]-l[g.id],0});
}else{
auto a=dn.top();
while(vis[a.id]){
dn.pop();
a=dn.top();
}
while(!lc.empty() && vis[lc.top().id]){
lc.pop();
}
if(ltd.empty() || lc.empty()){
ans+=a.val;
dn.pop();
vis[a.id]=1;
dtl.push(node{a.id,l[a.id]-d[a.id],0});
}else{
auto b=ltd.top();
auto c=lc.top();
if(a.val<=b.val+c.val){
ans+=a.val;
dn.pop();
vis[a.id]=1;
dtl.push(node{a.id,l[a.id]-d[a.id],0});
}else{
ans+=b.val+c.val;
ltd.pop();
lc.pop();
vis[c.id]=1;
dtl.push(node{b.id,l[b.id]-d[b.id],0});
ltd.push(node{c.id,d[c.id]-l[c.id],0});
}
}
}
printf("%lld\n",ans);
}
return 0;
}

gym102201E_Eat Economically的更多相关文章

  1. Why Countries Succeed and Fail Economically

    Countries Succeed and Fail Economically(第一部分)" title="Why Countries Succeed and Fail Econo ...

  2. Doherty Threshold

    Prior to the publication of the IBM technical paper behind what commonly known today as the Doherty ...

  3. Manifesto of the Communist Party

    A spectre is haunting Europe – the spectre of communism. All the powers of old Europe have entered i ...

  4. Toward Scalable Systems for Big Data Analytics: A Technology Tutorial (I - III)

    ABSTRACT Recent technological advancement have led to a deluge of data from distinctive domains (e.g ...

  5. 摘要评注The Cathedral & The Bazaar

    2013年暑期买到这本书,距离其第一版已经有14年之久,而最早发布在互联网上的文章更是早在1997年.在我阅读的时候,很多事迹已经沉积为历史,很多预言已经成为现实.而这本书的意义却丝毫没有因此淡化,反 ...

  6. English substitute

    英语写作中替换掉用到发腻的↓常用词↓,吐血整理2小时~~   动词替换:   1.Improve 提高:   Promote: 促进AC之间的贸易 promote the trade between ...

  7. How to Write Doc Comments for the Javadoc Tool

    http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html This document describe ...

  8. 越狱Season 1-Episode 6: Riots, Drills and the Devil: Part 1

    Season 1, Episode 6: Riots, Drills and the Devil: Part 1 - Diamond: Just a few more rides. 就再多玩几次吧 O ...

  9. Regionals 2013 :: North America - Southeast USA

    Regionals 2013 :: North America - Southeast USA It Takes a Village As a Sociologist, you are studyin ...

随机推荐

  1. 安装tomcat出现的问题

    今天在安装tomcat时出现了配置环境不对的问题. 在正确配置Tomcat环境变量后,遇到很多次运行startup.bat后,一个窗口一闪而过的. 解决方法: 1.在tomcat的目录下选中start ...

  2. Flume日志采集框架的使用

    文章作者:foochane  原文链接:https://foochane.cn/article/2019062701.html Flume日志采集框架 安装和部署 Flume运行机制 采集静态文件到h ...

  3. Java 并发:学习Thread 类

    Java 中 Thread类 的各种操作与线程的生命周期密不可分,了解线程的生命周期有助于对Thread类中的各方法的理解.一般来说,线程从最初的创建到最终的消亡,要经历创建.就绪.运行.阻塞 和 消 ...

  4. C#开发BIMFACE系列6 服务端API之获取文件信息

    在<C#开发BIMFACE系列4 服务端API之源上传文件>.<C#开发BIMFACE系列5 服务端API之文件直传>两篇文章中详细介绍了如何将本地文件上传到BIMFACE服务 ...

  5. runnable和thread实现多线程的区别

    下面以典型的买票程序(基本都是以这个为例子)为例,来说明二者的区别. 首先通过继承Thread类实现,代码如下: class MyThread extends Thread{ private int ...

  6. evevt

    EventEvent 是一个事件对象,当一个事件发生后,和当前事件发生相关的详细信息会被临时存储到一个指定的地方,也就是event对象,以方便我们在需要的时候调用. 在这一点上,非常类似于飞机当中的黑 ...

  7. Oracle - Tables

    创建表 a: Sql语句创建 -- Create table create table Table_Name ( 字段1 VARCHAR2(50), 字段2 VARCHAR2(50) not null ...

  8. 分享一个赚钱方法:用趣分类app在家轻松赚钱

    什么是趣分类 近期,垃圾分类是社会各界和广大市民关心的一个热门话题,随着垃圾分类工作的推进,各地都掀起学习垃圾分类的热潮.为了我们的美好生活,打响"垃圾分类"这场硬仗刻不容缓.据了 ...

  9. CodeForces 812E Sagheer and Apple Tree 树上nim

    Sagheer and Apple Tree 题解: 先分析一下, 如果只看叶子层的话. 那么就相当于 经典的石子问题 nim 博弈了. 那我们看非叶子层. 看叶子层的父亲层. 我们可以发现, 如果从 ...

  10. CodeForces 875 D High Cry

    High Cry 题解: 把思路转换成总-非法方案数. 对于第i个点来说 找到L[i], R[i] 然后 对于所有的在[ L[i], R[i] ]  的值都 < a[i], 然后对于第i个点来说 ...