转载声明:http://blog.youkuaiyun.com/u011345461/article/details/38537573
题意:给你一堆工作,有截止时间和需要的工作时间,问最多能做多少项任务.
个人感想:这类题目我是个人觉得很多时候都得用到优先队列,有2个限制优先,一个是截止时间,一个是工作时间长短,我想了很久也就只能想到截止时间,我觉得也会有很多人是这样子,无非就先按截止时间排个序,这大家都会想到,我想工作时间越短,工作截止时间越早的先做, 可是会发现
4
2 5
3 5
2 6
2 6 这样的任务你就只能做2个,我也考虑到用优先队列,但我没转过弯来!!
因为我们是按照截止时间来选择这些工作,而且开始的时间都是从(0,dealine-Need),如果当前不能选的工作的时间 必其中所选的所有工作所需的时间短,那么该工作必定能选!!而且使总工作时间更短,我们能选更多任务!! 做这类题必定要考虑到优先队列!! 某个条件解决了,就得从另外的条件进入.
分析:先按照截止时间进行排序,然后用优先队列维护所需工作时间.
代码:
/* Author:GavinjouElephant
* Title:
* Number:
* main meanning:
*
*
*
*/
//#define OUT
#include <iostream>
using namespace std;
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <sstream>
#include <cctype>
#include <vector>
#include <set>
#include <cstdlib>
#include <map>
#include <queue>
//#include<initializer_list>
//#include <windows.h>
//#include <fstream>
//#include <conio.h>
#define MaxN 0x7fffffff
#define MinN -0x7fffffff
#define Clear(x) memset(x,0,sizeof(x))
const int INF=0x3f3f3f3f;
const int maxn=800005;
int N;
class Point
{
public:
int Need;
int dealine;
};
Point p[maxn];
int T;
int Time;
int work;
bool cmp(const Point &a, const Point &b)
{
if(a.dealine!=b.dealine)return a.dealine<b.dealine;
return a.Need<b.Need;
}
void init()
{
Time=0;
work=0;
}
void solve()
{
priority_queue<int> q;
for(int i=0;i<N;i++)
{
if( p[i].Need+Time<=p[i].dealine)
{
Time+=p[i].Need;
q.push(p[i].Need);
work++;
}
else if(!q.empty())
{
int temp=q.top();
if(temp>p[i].Need)
{
Time=Time-temp+p[i].Need;
q.pop();
q.push(p[i].Need);
}
}
}
}
int main()
{
#ifdef OUT
freopen("coco.txt","r",stdin);
freopen("lala.txt","w",stdout);
#endif
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
init();
for(int i=0;i<N;i++)
{
scanf("%d%d",&p[i].Need,&p[i].dealine);
}
sort(p,p+N,cmp);
solve();
printf("%d\n",work);
if(T)printf("\n");
}
return 0;
}