题解-CF436E Cardboard Box
题面
\(n\) 个关卡,对每个关卡可以花 \(a_i\) 时间得到 \(1\) 颗星,或花 \(b_i\) 时间得到 \(2\) 颗星,或不玩。问获得 \(m\) 颗星最少需要多少时间。
数据范围:\(1\le n\le 3\cdot 10^5\),\(1\le m\le 2n\),\(a_i<b_i\)。
题解
蒟蒻做这题时已经知道是反悔贪心了,但是做了 \(4\) 个小时做不出来。于是去看题解,感觉这个 \(5\) 堆做法太非人类了,于是去看
CF题解和代码后总结出了蒟蒻的不用反悔贪心的做法和题解。
如果不反悔贪心,那么每一步必须保证没有后效性地最优。
很明显如果只有 \(a_i\),排序可以满足这个条件。
这题最朴素的错误做法是用一个小顶堆,刚开始把所有 \(a_i\) 丢进去,然后 \(m\) 次每次取堆顶,如果选了 \(a_i\) 把 \(b_i-a_i\) 也丢进去。
如果 \(a_i\) 都很大,\(b_i-a_i\) 都很小这样显然是亏的。
假如某个 \(i\) 打出 \(2\) 星是当前最优,如果 \(a_i\) 已经取了按照上面的办法肯定没有问题;但是如果 \(a_i\) 都没取,\(a_i\) 不一定是单个中的最优。
所以这篇题解最重要的骚操作就来了:选之前权衡,选两个的最优还是一个的最优:哪个更优?
可以用一个 vis 数组记录打了那些关卡,每次把打了的从堆中扔掉,这样就可以假定堆中的都是没有打过的了。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,n) for(int i(0);i<(n);++i)
#define L(i,n) for(int i((n)-1);~i;--i)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;
//Data
const int N=3e5,sN=N<<1;
int n,m,star[N];
ll a[sN],ns; bool vis[sN];
priority_queue<pair<ll,int>> o,t;
void ref(priority_queue<pair<ll,int>> &q){
while(sz(q)&&vis[q.top().y]) q.pop();
}
//Main
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>m;
R(i,n) cin>>a[i]>>a[i+n],a[i+n]-=a[i],
o.push(mp(-a[i],i)),t.push(mp(-a[i]-a[i+n],i));
while(m--){
ref(o),ref(t);
int i=o.top().y; o.pop(),ref(o);
if(m&&sz(t)&&a[i]-o.top().x>=-t.top().x)
o.push(mp(-a[i],i)),i=t.top().y,t.pop();
i<n&&(o.push(mp(-a[i+n],i+n)),true);
ns+=a[i],star[i%n]++,vis[i]=true;
}
cout<<ns<<'\n';
R(i,n) cout<<star[i],i==n-1&&(cout<<'\n');
return 0;
}
/*
可以考虑不反悔:权衡一个两个哪个优!
*/
祝大家学习愉快!
题解-CF436E Cardboard Box的更多相关文章
- CF436E Cardboard Box(贪心)
题意 有nnn个关卡,第iii关可以花费aia_iai的代价打一颗星,bib_ibi的代价打两颗星.保证1≤ai<bi≤1091\le a_i<b_i\le10^91≤ai<b ...
- Codeforces 436E Cardboard Box (看题解)
Cardboard Box 贪了个半天贪不对, 我发现我根本就不会贪心. 我们先按b排序, 然后枚举选两颗心的b的最大值, 在这个之前的肯定都要选一个, 因为前面的要是一个都没选的话, 你可以把当前选 ...
- 题解 CF1428A 【Box is Pull】
通过理解题意,我们发现: 当需要拐弯的时候,兔子需要先走回箱子的位置,再走向拐弯的方向.则拐弯操作的花费为 \(2\) .而直行的操作花费为 \(1\) . 所以, 如果不需要拐弯,也就是 \(x1= ...
- Codeforces 436E - Cardboard Box(贪心/反悔贪心/数据结构)
题面传送门 题意: 有 \(n\) 个关卡,第 \(i\) 个关卡玩到 \(1\) 颗星需要花 \(a_i\) 的时间,玩到 \(2\) 颗星需要 \(b_i\) 的时间.(\(a_i<b_i\ ...
- upc组队赛12 Cardboard Container【枚举】
Cardboard Container Problem Description fidget spinners are so 2017; this years' rage are fidget cub ...
- uva 580 危险的组合(排列组合)
Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu Submit Status Descript ...
- CF数据结构练习
1. CF 438D The Child and Sequence 大意: n元素序列, m个操作: 1,询问区间和. 2,区间对m取模. 3,单点修改 维护最大值, 取模时暴力对所有>m的数取 ...
- SGU 495. Kids and Prizes
水概率....SGU里难得的水题.... 495. Kids and Prizes Time limit per test: 0.5 second(s)Memory limit: 262144 kil ...
- Kids and Prizes(SGU 495)
495. Kids and Prizes Time limit per test: 0.25 second(s)Memory limit: 262144 kilobytes input: standa ...
随机推荐
- 1、线性DP 213. 打家劫舍 II
https://leetcode-cn.com/problems/house-robber-ii/ //rob 0, not rob n-1 || not rob 0,not rob n-1 ==&g ...
- 新手避坑 -- 用 Jenkins +miniprogram-ci 自动构建微信小程序
先看看效果: 要实现这样的效果,需要下面3步: 1.下载 node 依赖包 miniprogram-ci,编写预览和上传功能 2. 登录微信公众平台, 下载项目的privateKey+添加代码上传IP ...
- Redis分布式锁的正确使用与实现原理
模拟一个电商里面下单减库存的场景. 1.首先在redis里加入商品库存数量. 2.新建一个Spring Boot项目,在pom里面引入相关的依赖. <dependency> <gro ...
- openstack常用命令-nova篇
1.查看openstack版本 nova-manage version 2.查看节点 nova host-list 3.查看计算节点 nova hypervisor-list 4.查看计算节点上有哪些 ...
- Java8 方法引用和构造方法引用
如果不熟悉Java8新特性的小伙伴,初次看到函数式接口写出的代码可能会是一种懵逼的状态,我是谁,我在哪,我可能学了假的Java,(・∀・(・∀・(・∀・*),但是语言都是在进步的,就好比面向对象的语言 ...
- Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)复现
Apache Shiro 1.2.4反序列化漏洞(CVE-2016-4437)复现 环境搭建 docker pull medicean/vulapps:s_shiro_1 docker run -d ...
- scala中的val,var和lazy
转自:https://yerias.github.io/2020/03/19/scala/3/#3%EF%BC%9Alazy%E4%BF%AE%E9%A5%B0%E7%AC%A6%E5%8F%AF%E ...
- Thread.start() ,它是怎么让线程启动的呢?
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...
- Vue 3.0 升级指南
本文由葡萄城技术团队原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 2020年9月18日Vue 3.0正式发布,距离2016年10月1日Vue ...
- 【震惊】手把手教你用python做绘图工具(一)
在这篇博客里将为你介绍如何通过numpy和cv2进行结和去创建画布,包括空白画布.白色画布和彩色画布.创建画布是制作绘图工具的前提,有了画布我们就可以在画布上尽情的挥洒自己的艺术细胞. 还在为如何去绘 ...