题目描述
小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者。但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏。现在的情况是:T部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。
输入格式
第一行是一个整数N,接下来N行每行两个整数T1,T2描述一个建筑:修理这个建筑需要T1秒,如果在T2秒之内还没有修理完成,这个建筑就报废了。
输出格式
输出一个整数S,表示最多可以抢修S个建筑.
输入输出样例
输入 #1复制
4
100 200
200 1300
1000 1250
2000 3200
输出 #1复制
3
添加链接描述
解题思路:
①按建筑的报废时间从小到大排序,最迫切的先修,也就是谁快坏了就先修谁
②请看例子
3
200 200
101 300
201 400
如果只按t2排序我们先修了第一个后,当前时间在200,200+101>300,所以第二个修不了,我们在看第三个,200+201>400,所以第三个也修不了,这样得出的是1,但事实上,应该能修2和3
所以,我们在修了第一个后,判断200+101>300时,我们不该直接放弃这个,都是只能修一个,我们要修2号,不修1号,因为修完2号当前的时间短。
#include<iostream>
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
int t1;
int t2;
}a[1500005];
int cmp(struct node z,struct node x)
{
if(z.t2!=x.t2)
return z.t2<x.t2;
else
return z.t1<x.t1;
}
struct cmp1//队列从大到小排序
{
bool operator()(int a,int b)
{
return a<b;
}
};
int main()
{
int n;
priority_queue<int,vector<int>,cmp1> q;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d %d",&a[i].t1,&a[i].t2);
}
sort(a,a+n,cmp);
int s=0;
int sum=0;
for(int i=0;i<n;i++)
{
if(sum+a[i].t1>a[i].t2)
{
if(a[i].t1<q.top())
{
sum=sum-q.top()+a[i].t1;
q.pop();
q.push(a[i].t1);
}
}
else
{
sum=sum+a[i].t1;
q.push(a[i].t1);
s++;
}
}
printf("%d\n",s);
return 0;
}