『UVA 1153』顾客是上帝

转载声明: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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值