hdu 6180 Schedule(贪心)

来源:互联网 发布:索尼手机更新软件 编辑:程序博客网 时间:2024/06/05 00:34

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6180

思路:

1.贪心。将每个安排分成两个:起始(标号为0)和终止(标号为1)。按照时间顺序排序,每次遇到一个起始事件时,num++(代表当前机器不能满足条件,需要一台新的机器);每次遇到一个终止事件时,num--(代表当前机器运行结束)。则机器个数=max{num}(代表同时运行的机器个数)。

2.时间计算。时间=完成工作的时间+等待时间。工作时间可通过输入时累加,等待时间可通过用一栈记录当前完成工作的结束时间。当遇到一起始事件时,等待时间=起始事件时间-当前最后工作的完成时间(即栈顶元素),同时出栈。当遇到一终止事件时,将该事件的时间入栈。

3.若起始时间与终止时间相同时,应先按照终止时间排序(可以理解为将所有终止时间往左移动了一个极小(大于0)的距离)。

#include<stack>#include<cstdio>#include<vector>#include<cstring>#include<iostream>#include<algorithm>#define debugusing namespace std;typedef long long LL;const int maxn=200000+50;struct Node{    LL x;    int id;    Node() {}    Node(LL x,int id):x(x),id(id) {}};LL sum;;stack<LL> s;Node a[maxn];int ans,n,num,cnt;int cmp(Node a,Node b){    if(a.x==b.x) return a.id>b.id;    else return a.x<b.x;}void init(){    ans=0,sum=0,num=0,cnt=0;    while(!s.empty()) s.pop();}int main(){#ifdef debu    freopen("1010.in","r",stdin);#endif // debug    int t;    scanf("%d",&t);    while(t--)    {        init();        scanf("%d",&n);        for(int i=0; i<n; i++)        {            LL l,r;            scanf("%lld%lld",&l,&r);            a[cnt++]=Node(l,0);            a[cnt++]=Node(r,1);            sum+=r-l;        }        sort(a,a+cnt,cmp);        for(int i=0; i<cnt; i++)        {            if(a[i].id==0)            {                num++;                if(!s.empty())                {                    LL pre=s.top();                    s.pop();                    sum+=a[i].x-pre;                }            }            else            {                num--;                s.push(a[i].x);            }            ans=max(ans,num);        }        printf("%d %lld\n",ans,sum);    }    return 0;}



原创粉丝点击