hdu 6180 Schedule(貪心)

題目地址: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 debug
using 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;
}



發佈了381 篇原創文章 · 獲贊 6 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章