1 A
1.1 Description
LZGZ的宿舍一间房可以住八个人,附赠一间独立的卫生间和一间独立的浴室。然而尽管老师再怎么强调回到宿舍一定要抓紧时间洗漱,还是有一堆的同学沉迷各种事情,直到熄灯了才去洗澡。问题在于柳州高中的热水并不是无间断供应的,比如说中午就不供应热水,晚上熄灯之后水温就会逐渐降低,直至变成冷水。
于是,在寒冷的冬天,晚上宿舍熄灯一段时间之后,浴室里的水就会变得相当寒冷,洗澡的同学就会感到极其痛苦。当然,不同的人对于冷水的忍耐力是不一样的。
我们不妨记同学们开始洗澡的时间为 0,一个同学洗澡耗时为 T1,而时间一旦超过 T2,则他(她)就会感到十分痛苦。请注意,如果这个同学在洗澡的过程中外部时间超过了 T2,他(她)依然会感到十分
痛苦。
一般地,宿舍的人越多,能舒服地洗澡的同学的数量就越少,但是也不绝对。
假如你是总社长,你会如何安排同学们的入浴顺序,使得有最多的同学能舒服地洗澡呢?
当然,如果只考虑一间只有 8 个人的宿舍,这个问题未免太过简单,你需要处理人数为 n 时的情况。
1.2 Input
第一行输入一个整数 n,表示宿舍人数。
接下来的 n 行,每行 2 个整数 T1、T2,描述一个同学的入浴耗时和忍耐时间。
1.3 Output
输出一个整数表示最多可以舒服地洗澡的同学的个数。
1.4 Example
input:
4
100 200
200 130
1000 1250
2000 3200
output:
3
1.5 Hint
对于 50% 的数据,1 ≤ n ≤ 103。
对于 100% 的数据,1 ≤ n ≤ 103 ,0 < T1 < T2 < 231 − 1。
下面是题解时间(你自己写过了吗?)
看到这个题目,想必很多人想到了贪心,但是注意,这并不是普通的贪心,而是 可撤销贪心
可以看看 P3045 [USACO12FEB]牛券Cow Coupons
什么是可撤销贪心呢?
通俗的说,就是已经贪心的选取的物品被更优的方案替代,也就是换掉已取过的物品。
放到这题上来说,就是我们先让一个人去洗澡,如果有必要的话,再把他 裸着 拉出来,换一个人进去
先上代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<queue> typedef long long LL; using namespace std; const LL N=1e6+3; struct node{LL a,b;}t[N]; bool cmp_for_MAXB(node x,node y){ return x.b<y.b; } int main(){ freopen("a.in","r",stdin); freopen("a.out","w",stdout); priority_queue<int>Q; LL n,used=0,tot=0; scanf("%I64d",&n); for(LL i=1;i<=n;++i) scanf("%I64d%I64d",&t[i].a,&t[i].b); sort(t+1,t+1+n,cmp_for_MAXB); for(LL i=1;i<=n;++i){ if(used+t[i].a<=t[i].b){ Q.push(t[i].a); ++tot; used+=t[i].a; }else{ if(used-Q.top()+t[i].a<=t[i].b&&t[i].a<Q.top()){ used=used-Q.top()+t[i].a; Q.pop(); Q.push(t[i].a); } } }printf("%I64d",tot); return 0; }
其实就是几块部分
sort(t+1,t+1+n,cmp_for_MAXB);
按照T2洗完澡的时间排序 (如果T2小的在前面就连选择的余地都没有了...),应该很好理解,按T1排序没什么用,因为洗的快的也可以靠后洗~qwq
//used是已经用掉的时间
for(LL i=1;i<=n;++i){ if(used+t[i].a<=t[i].b){ //如果时间足以让这个人洗完 , 就洗吧 Q.push(t[i].a); ++tot; used+=t[i].a; }else{ //如果把最浪费时间的人扯出来,能让这人洗完,并且这人不比被扯出来的人耗时长,就换人 if(used-Q.top()+t[i].a<=t[i].b&&t[i].a<Q.top()){ used=used-Q.top()+t[i].a; Q.pop(); Q.push(t[i].a); } } }
一般可撤销贪心都会使用优先队列来找出替换掉哪个更优。
显然无论怎么贪心,都有一条原则: 我们一定不能亏!
总结
贪心的题目要么做出来,要么做不出而且看了题解恍然大悟自己却就是想不到。
所以要多见识各种模型,才能更好的练习思维。