专题突破之反悔贪心——建筑抢修,Cow Coupons G, Voting (Hard Version),Cardboard Box
文章目录
- [JSOI2007]建筑抢修
- [USACO12FEB]Cow Coupons G
- CF1251E2 Voting (Hard Version)
- CF436E Cardboard Box
[JSOI2007]建筑抢修
luogu4053
将建筑按照结束时间从小到大排序
然后记录一下已经修理的建筑总共的花费时间
如果花费时间加上现在这个建筑的修建时间超过了这个建筑的结束时间
就考虑反悔最长修建时间的建筑(必须要比现在的这个建筑修建时间长才行)
用大根堆维护即可
如果没有比现在这个建筑更长时间的已修建的建筑,那么这个建筑就无法被修建
这个贪心的原理是:建筑之间没有权值,换言之修建任何一个建筑的收益是等价的,那么排序后就尽可能地腾出更多的空闲时间给后面的建筑修建
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
#define maxn 150005
struct node { int ti, lim; }v[maxn];
priority_queue < int > q;
int n;signed main() {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ )scanf( "%lld %lld", &v[i].ti, &v[i].lim );sort( v + 1, v + n + 1, []( node x, node y ) { return x.lim < y.lim; } );int now = 0, ans = 0;for( int i = 1;i <= n;i ++ ) {if( now + v[i].ti <= v[i].lim )now += v[i].ti, q.push( v[i].ti ), ans ++;else {if( ! q.empty() and q.top() > v[i].ti )now -= q.top(), now += v[i].ti, q.pop(), q.push( v[i].ti );}}printf( "%lld\n", ans );return 0;
}
[USACO12FEB]Cow Coupons G
luogu3045
按每头牛的打折后的c从小到大排序
考虑前kkk头牛肯定是都把优惠券用了,然后进入反悔堆,p-c
而后考虑两种情况
- 不用优惠券,就是原价购买,这需要对第kkk头牛后面的所有牛进行原价的排序,用小根堆维护
- 用优惠券,反悔一张效果最差的(也就是
p-c
最小的)加上这头牛打折后的价格,就是反悔后的花费
两个取较小值与现在的金额比较即可
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 500005
#define int long long
#define Pair pair < int, int >
#define inf 1e18
priority_queue < int, vector < int >, greater < int > > q;
priority_queue < Pair, vector < Pair >, greater < Pair > > q1, q2;
struct node { int p, c; }cow[maxn];
int n, m, k;
bool vis[maxn];signed main() {scanf( "%lld %lld %lld", &n, &k, &m ); for( int i = 1;i <= n;i ++ ) scanf( "%lld %lld", &cow[i].p, &cow[i].c );sort( cow + 1, cow + n + 1, []( node x, node y ) { return x.c < y.c; } );for( int i = 1;i <= k;i ++ ) {if( cow[i].c <= m ) m -= cow[i].c, q.push( cow[i].p - cow[i].c );else return ! printf( "%lld\n", i - 1 );}if( k == n ) return ! printf( "%lld\n", n );int ans = k;for( int i = k + 1;i <= n;i ++ ) {q1.push( make_pair( cow[i].c, i ) );q2.push( make_pair( cow[i].p, i ) );}q.push( inf );q1.push( make_pair( inf, 0 ) );q2.push( make_pair( inf, 0 ) );while( 1 ) {while( vis[q1.top().second] ) q1.pop(); while( vis[q2.top().second] ) q2.pop();int i1 = q1.top().second;int i2 = q2.top().second;int w1 = q.top() + q1.top().first;int w2 = q2.top().first;if( min( w1, w2 ) > m ) break;ans ++; m -= min( w1, w2 );if( w1 < w2 )q.pop(), q1.pop(), vis[i1] = 1, q.push( cow[i1].p - cow[i1].c );elseq2.pop(), vis[i2] = 1;}printf( "%lld\n", ans );return 0;
}
CF1251E2 Voting (Hard Version)
CF1251E2
如果将mmm的限制变成时间限制,第iii个人的投票必须在n−mi−1n-m_i-1n−mi−1的时间以前(包括这个时刻)
注意:是以0时刻开始算起的
投票,否则就会产生pip_ipi的罚款
这就巧妙地转化成了贪心经典——不守交规
按照截止时间排序,每个人投票需要一个时间
- 如果时间还有剩,这个人就可以不被罚
- 如果没有剩,那么往前面找最小的罚金(必须比现在的罚金小)
- 有就选择交换这两个人的投票时间,将这个人入反悔堆,罚金是不可避免的,只不过变成了交最小的罚金
- 没有就老老实实让这个人交罚金
#include <queue>
#include <cstdio>
#include <algorithm>
using namespace std;
#define int long long
#define maxn 200005
struct node { int p, m; }vote[maxn];
priority_queue < int, vector < int >, greater < int > > q;
int T, n;signed main() {scanf( "%lld", &T );while( T -- ) {scanf( "%lld", &n );for( int i = 1;i <= n;i ++ ) {scanf( "%lld %lld", &vote[i].m, &vote[i].p );vote[i].m = n - vote[i].m - 1;}sort( vote + 1, vote + n + 1, []( node x, node y ) { return x.m < y.m; } );while( ! q.empty() ) q.pop();int ans = 0;for( int i = 1;i <= n;i ++ )if( q.size() <= vote[i].m ) q.push( vote[i].p );elseif( ! q.empty() and q.top() < vote[i].p )ans += q.top(), q.pop(), q.push( vote[i].p );elseans += vote[i].p;printf( "%lld\n", ans );}return 0;
}
CF436E Cardboard Box
CF436E
- 贪心操作1:选择激活某个关卡的第一颗星 花费为最小的aiaiai
- 贪心操作2:选择激活某个关卡的第二颗星 花费为最小的bj−ajbj-ajbj−aj
- 反悔操作1:反悔最大花费的只激活了第一颗星的关卡 直接将花费最小的未激活关卡激活完2颗星 花费为bi−ajbi-ajbi−aj
- 反悔操作2:反悔最大花费的2颗星全激活的关卡 直接将花费最小的未激活关卡2颗星激活完 花费为bi−(bj−aj)bi-(bj-aj)bi−(bj−aj)
直接开五个堆维护,代码里有详细注释
#include <queue>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define Pair pair < int, int >
#define int long long
#define maxn 300005
#define inf 1e18
priority_queue < Pair, vector < Pair >, greater < Pair > > q1, q2, q3;
priority_queue < Pair > q4, q5;
int n, m;
int ans[maxn], a[maxn], b[maxn];/*
q1: 关卡激活为0颗星的a贪心策略1:选择花费最小的还是0颗星的关卡激活成1颗星小根堆
q2: 关卡激活为1颗星的b-a贪心策略2:选择花费最小的激活1颗星的关卡激活成2颗星小根堆
q3: 关卡激活为0颗星的b反悔策略12:回收一颗星后直接激活最小花费某个关卡的两颗星小根堆
q4: 关卡激活为1颗星的a反悔策略1:反悔最大花费的激活1颗星的关卡操作变成激活为0大根堆
q5: 关卡激活为2颗星的b-a返回策略2:反悔最大花费的激活2颗星的关卡操作变成只激活1大根堆
*/void add0( int x ) {ans[x] = 0;q1.push( make_pair( a[x], x ) );q3.push( make_pair( b[x], x ) );
}void add1( int x ) {ans[x] = 1;q2.push( make_pair( b[x] - a[x], x ));q4.push( make_pair( a[x], x ) );
}void add2( int x ) {ans[x] = 2;q5.push( make_pair( b[x] - a[x], x ) );
}signed main() {scanf( "%lld %lld", &n, &m );q1.push( make_pair( inf, n + 1 ) );q2.push( make_pair( inf, n + 1 ) );q3.push( make_pair( inf, n + 1 ) );q4.push( make_pair( -inf, n + 1 ) );q5.push( make_pair( -inf, n + 1 ) ); for( int i = 1;i <= n;i ++ ) {scanf( "%lld %lld", &a[i], &b[i] );add0( i );}int ret = 0;for( int i = 1;i <= m;i ++ ) {int i1 = q1.top().second;int i2 = q2.top().second;int i3 = q3.top().second;int i4 = q4.top().second;int i5 = q5.top().second;while( q1.size() > 1 and ans[i1] ^ 0 ) q1.pop(), i1 = q1.top().second;while( q2.size() > 1 and ans[i2] ^ 1 ) q2.pop(), i2 = q2.top().second;while( q3.size() > 1 and ans[i3] ^ 0 ) q3.pop(), i3 = q3.top().second;while( q4.size() > 1 and ans[i4] ^ 1 ) q4.pop(), i4 = q4.top().second;while( q5.size() > 1 and ans[i5] ^ 2 ) q5.pop(), i5 = q5.top().second;int w1 = q1.top().first;int w2 = q2.top().first;int w3 = q3.top().first;int w4 = q4.top().first;int w5 = q5.top().first;//i:表示未激活的关卡 j:表示已激活的关卡 int t1 = w1; //贪心操作1:选择激活某个关卡的第一颗星 花费为最小的aiint t2 = w2; //贪心操作2:选择激活某个关卡的第二颗星 花费为最小的bj-ajint t3 = w3 - w4; //反悔操作1:反悔最大花费的只激活了第一颗星的关卡 直接将花费最小的未激活关卡激活完2颗星 花费为bi-aj int t4 = w3 - w5; //反悔操作2:反悔最大花费的2颗星全激活的关卡 直接将花费最小的未激活关卡2颗星激活完 花费为bi-(bj-aj) int Min = min( min( t1, t2 ), min( t3, t4 ) );ret += Min;if( Min == t1 ) q1.pop(), add1( i1 );else if( Min == t2 ) q2.pop(), add2( i2 );else if( Min == t3 ) q3.pop(), q4.pop(), add2( i3 ), add0( i4 );else q3.pop(), q5.pop(), add2( i3 ), add1( i5 );}printf( "%lld\n", ret );for( int i = 1;i <= n;i ++ ) printf( "%lld", ans[i] );return 0;
}
专题突破之反悔贪心——建筑抢修,Cow Coupons G, Voting (Hard Version),Cardboard Box相关推荐
- P4053 [JSOI2007] 建筑抢修(反悔贪心)
P4053 [JSOI2007] 建筑抢修https://www.luogu.com.cn/problem/P4053 #include <iostream> #include <c ...
- 【JSOI2007】【BZOJ1029】【codevs2913】建筑抢修,贪心与堆
1029: 建筑抢修 Time Limit: 4 Sec Memory Limit: 162 MB Submit: 3109 Solved: 1396 [Submit][Status][Discuss ...
- BZOJ 1029: [JSOI2007]建筑抢修 堆+贪心
1029: [JSOI2007]建筑抢修 Description 小刚在玩JSOI提供的一个称之为"建筑抢修"的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的 入侵者.但 ...
- BZOJ 1029: [JSOI2007]建筑抢修【贪心】
1029: [JSOI2007]建筑抢修 Time Limit: 4 Sec Memory Limit: 162 MB Description 小刚在玩JSOI提供的一个称之为"建筑抢修&q ...
- 【bzoj1029】【JSOI2007】建筑抢修
1029: [JSOI2007]建筑抢修 Time Limit: 4 Sec Memory Limit: 162 MB Submit: 6417 Solved: 2883 [Submit][Sta ...
- Bzoj1029 [JSOI2007]建筑抢修
Time Limit: 4 Sec Memory Limit: 162 MB Submit: 4452 Solved: 2006 Description 小刚在玩JSOI提供的一个称之为" ...
- bz 1029: [JSOI2007]建筑抢修
1029: [JSOI2007]建筑抢修 Time Limit: 4 Sec Memory Limit: 162 MB Submit: 3104 Solved: 1392 [Submit][Sta ...
- 洛谷——P4053 [JSOI2007]建筑抢修
P4053 [JSOI2007]建筑抢修 小刚在玩JSOI提供的一个称之为"建筑抢修"的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个 ...
- 【每日一题】【[JSOI2007]建筑抢修】
题目描述 小刚在玩JSOI提供的一个称之为"建筑抢修"的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不 ...
最新文章
- Flex精华摘要--使用AS脚本
- 刻意练习:LeetCode实战 -- Task30.通配符匹配
- 7-7 12-24小时制 (C语言)
- 如何“愚弄”人工智能?
- [转]收录全部作品,《寂静岭套装》发售开始
- 老婆,我会好好爱你的
- 洛谷 P2296 寻找道路
- 通俗易懂,java8 .stream().map().collect()用法
- SpringMVC—对Ajax的处理(含 JSON 类型)(2)
- 利用结构体数组实现重排序(详解)
- jeesite导出Excel Minimum column number is 0
- Vue.Draggable拖拽功能的配置和使用方法
- 修改了一个YUV/RGB播放器
- 读凤凰网经典语句记录一
- Stanford Parser demo错误:Unsupported major.minor version 52.0 error
- 5. JavaScript Number 对象
- php全表搜索,搜索整个表? PHP MySQL
- ARM汇编指令集与机器码
- 报错Error configuring application listener of class jdbc.ContextListener 解决办法之一
- win环境安装October CMS
热门文章
- 限时秒杀┃秒杀90%的玩具,让孩子爱上科学的彩虹实验2来了!
- 孩子不是笨,他和“最强大脑”差的是这个!
- 计算机常用编程英语词汇大全,计算机编程及常用术语英语词汇大全
- php文件上传实验总结,53 PHP文件处理(六)文件上传--总结---细说php
- java跨库调用存储_存储库仅在第二个调用数据时发送回ViewModel
- arma3自定义服务器,Arma3 生存服架设教程,武装突袭3游戏服务器架设
- docker 容器启动顺序_Docker容器启动时初始化Mysql数据库
- 7-52 两个有序链表序列的交集 (20 分)(思路加详解尾插法)come Boby!
- 7-47 打印选课学生名单 (25 分)(两种做法)(思路加详解+map+vector做法+最后一个点超时解决)+兄弟们冲丫丫
- [mybatis]Configuration XML_mappers