专题突破之反悔贪心——建筑抢修,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-1nmi1的时间以前(包括这个时刻)

注意:是以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-ajbjaj
  • 反悔操作1:反悔最大花费的只激活了第一颗星的关卡 直接将花费最小的未激活关卡激活完2颗星 花费为bi−ajbi-ajbiaj
  • 反悔操作2:反悔最大花费的2颗星全激活的关卡 直接将花费最小的未激活关卡2颗星激活完 花费为bi−(bj−aj)bi-(bj-aj)bi(bjaj)

直接开五个堆维护,代码里有详细注释

#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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317125.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Max Sum Plus Plus HDU - 1024

Max Sum Plus Plus HDU - 1024 题意&#xff1a; 给你n个数&#xff0c;选m个子段&#xff0c;各个子段连续且不相交&#xff0c;长度可以为1&#xff0c;设maxn为各个子区间的和&#xff0c;求最大的maxn。 题解&#xff1a; 设dp[i][j]表示前j个数分成i段的最大值 对于第…

模板:杜教筛(莫比乌斯反演、数论)

所谓杜教筛&#xff0c;就是dms教给我们的筛 &#xff08;逃&#xff09; 前言 与其说算法&#xff0c;不如说是技巧。 可以在低于线性的时间复杂度&#xff08;准确的说是 O(n23)O(n^{\frac{2}{3}})O(n32​)&#xff09;内完成对积性函数的前缀和计算。 解析 考虑求函数 f…

程序员过关斩将--快速迁移10亿级数据

菜菜呀&#xff0c;咱们业务BJKJ有个表数据需要做迁移程序员主力 Y总现在有多少数据&#xff1f;菜菜大约21亿吧&#xff0c;2017年以前的数据没有业务意义了&#xff0c;给你半天时间把这个事搞定&#xff0c;绩效给你A程序员主力 Y总有绩效奖金吗&#xff1f;菜菜钱的事你去问…

[2021-09-09 T2] 就差⼀点——冒泡排序和反序表之间不为人知的秘密

就差一点解题报告descriptionsolutioncodedescription 题目描述 冒泡排序是⼀个简单的排序算法&#xff0c;其时间复杂度为O(n2)O(n^2)O(n2) 有⼀个大小为nnn的排列p1,...,pnp_1,...,p_np1​,...,pn​&#xff0c;⼩明想对这个排列进⾏冒泡排序&#xff0c;于是写了下⾯这份…

CodeForces - 76E Points

CodeForces - 76E Points 题意&#xff1a; 给你n个点的坐标&#xff0c;求所有一对点之间的距离的平方和 n<100000 题解&#xff1a; 直接暴力n2肯定不行&#xff0c;我们把这个的式子列出来&#xff1a; 代码&#xff1a; #include<bits/stdc.h> #define deb…

模板:Miller-RabinPollard-Rho(数论)

所谓 pollard-rho&#xff0c;就是泼辣的肉 &#xff08;逃&#xff09; 前言 许多题解都把这两个算法放在了一起。 那我也这样办吧&#xff01; miller-rabin可以在优秀的时间复杂度内完成对一个数的素性检测。 而pollard-rho则是立足于Miler-rabin之上&#xff0c;可以在 …

Asp.NetCore轻松学-部署到 Linux 进行托管

前言上一篇文章介绍了如何将开发好的 Asp.Net Core 应用程序部署到 IIS&#xff0c;且学习了进程内托管和进程外托管的区别&#xff1b;接下来就要说说应用 Asp.Net Core 的特性&#xff08;跨平台&#xff09;&#xff0c;将 .NetCore 部署到 Linux 中&#xff0c;主流的 Linu…

DevC++ 用C语言的多线程 实现简单的客户端和服务器

知识来源一&#xff1a; 使用Dev-C实现简单的客户端和服务器-CSDN博客 此先生的博客使用的是win32 SDK来创建多线程&#xff0c;然后鄙人对这个版本的多线程细节不明。于是又重新用C语言的线程替代win32API,以此继续学习服务器代码。 知识来源二&#xff1a;DevC 多线程创建…

[2021-09-09 T3] 序列/luogu P3943 星空(异或差分+bfs最短路+状压dp)

序列descriptionsolutioncodedescription 题目描述 长度为nnn的序列&#xff0c;初始全为000&#xff0c;每次可以选择⼀个数ai(1≤i≤l)a_i(1\le i\le l)ai​(1≤i≤l)&#xff0c;然后选择连续aia_iai​个元素异或上111 求最少的次数&#xff0c;使得对于所有i(1≤i≤k)i(…

HDU - 4608 I-number

题意&#xff1a; 给你一个x&#xff0c;让你构造一个y&#xff0c;y的要求&#xff1a; y>xy的各项之和为10的倍数在满足前两个的前提下&#xff0c;y尽可能小 题解&#xff1a; 模拟&#xff0c;尽可能的模拟&#xff0c;用字符串模拟 先将各位相加得到sum&#xff0c…

从初创公司的角度来看微服务

在开展微服务的过程中&#xff0c;了解要考虑哪些因素可能是非常有挑战性的事情。没有可以直接使用的金科玉律。每个过程都是不同的&#xff0c;因为每个组织面临的都是不同的环境。在本文中&#xff0c;我将从初创公司的角度分享我们学习到的经验和面临的挑战&#xff0c;以及…

洛谷P2056:[ZJOI2007]捉迷藏(点分树、STL)

解析 见到动态维护最远点对&#xff0c;不难想到利用 set 维护最大值和次大值&#xff0c;每个点维护两个 set 的杂技做法。 但是问题是…T了啊。 咋办嘞。 一个在本题至关重要的 trick&#xff1a;利用两个堆来支持访问最大值和删除 具体也很好理解&#xff1a;当删除的时候…

[NOI2018] 归程(线段树维护并查集的可持久化/kruskal重构树,倍增+dijkstra最短路)

[NOI2018] 归程descriptionsolution1code1solution2codedescription 题目描述 本题的故事发生在魔力之都&#xff0c;在这里我们将为你介绍一些必要的设定 魔力之都可以抽象成一个nnn个节点、mmm条边的无向连通图&#xff08;节点的编号从111至nnn&#xff09;我们依次用 l,…

CodeForces - 616D Longest k-Good Segment

CodeForces - 616D Longest k-Good Segment 题意&#xff1a; 有包含n个数的序列a&#xff0c;求能找到最长的区间包含不超过k个不同的元素。 题解&#xff1a; 尺取法&#xff0c;先固定L&#xff0c;然后移动R&#xff0c;R每次移动&#xff0c;当超过k后&#xff0c;L再…

MySQL 集群方案介绍

mysql集群方案这里介绍2种&#xff0c;PXC 和 Replication。大型互联网程序用户群体庞大&#xff0c;所以架构设计单节点数据库已经无法满足需求。大家也深有体会&#xff0c;有一万人在学校网站查成绩或是选课的时候网站时常是访问不了或者相应特别特别慢。这种情况就凸显出来…

模板:回文自动机(PAM)

所谓回文自动机&#xff0c;就是关于回文的自动机。 &#xff08;逃&#xff09; 前言 小清新自动机。 经历过SAM的大风大浪&#xff0c;这个相比而言好理解多了&#xff0c;感觉也许应该先学这个再学SAM… 解析 和trie、AC自动机、SAM等类似的&#xff0c;PAM的每个结点表…

Gym - 215177C 玩游戏

题意&#xff1a; ljcc和他的学妹在玩游戏&#xff0c;这个游戏共有 n 轮&#xff0c;在第 i 轮获胜会获得 i 分&#xff0c;没有平局。 现在给出ljcc和学妹的得分&#xff0c;求是否有一种方案符合当前得分。 题解&#xff1a; 第i轮得到i分&#xff0c;一共n轮&#xff0…

Zju2112 Dynamic Rankings(树状数组套可持久化权值线段树)

Zju2112 Dynamic Rankingsdescriptionsolutioncodedescription 给定一个含有n个数的序列a[1],a[2],a[3]……a[n]&#xff0c;程序必须回答这样的询问&#xff1a;对于给定的i,j,k&#xff0c;在a[i],a[i1 ],a[i2]……a[j]中第k小的数是多少(1≤k≤j-i1)&#xff0c;并且&…

ML.NET案例详解:在.NET下使用机器学习API实现化学分子式数据格式的判定

半年前写过一篇类似的文章&#xff0c;题目是&#xff1a;《在.NET中使用机器学习API&#xff08;ML.NET&#xff09;实现化学分子式数据格式的判定》&#xff0c;在该文中&#xff0c;我介绍了化学分子式数据格式的基本知识&#xff0c;同时给出了一个案例&#xff0c;展示了如…

洛谷P4762: [CERC2014]Virus synthesis(PAM)

解析 自己对PAM的理解不够深刻。 最优方案必然是先选择一个偶回文串&#xff0c;递归构造出它的一半。花一步逆序&#xff0c;然后暴力解决剩下的。 这似乎已经依稀出现了某种dp的思路。 考虑如何更好的转移。设计 transxtrans_xtransx​ 表示长度不超过 xxx 一半的最长回文后…