第十场 hdu 6180 Schedule (multiset)/(思维)

http://acm.hdu.edu.cn/showproblem.php?pid=6180

 

题目大意:

已知一些商品制作的开始和结束时间,问在使用最少的机器的前提下机器工作的最少的总时间是多少??
 
解题思路:
 
解法一:
如何求出至少要多少台机器:
把时间段转化成一个入点和一个出点,这样存下2*n个点,之后按坐标从小到大给这2*n个点排序,之后O(n)遍历一遍就好,遇到入点sum++, 遇到出点sum--,遍历时最大的sum便是答案,算上排序复杂度稳定nlogn(注意:排序时坐标相同的点出点优先)
时间求法也很容易:
如果当前sum=5,而ans=4(也就是当前不得不用第5台机器),那么记录下入点的时间,说明第5台机器在这个时候开始使用,同理,第1,2,6,7,8…台机器都一样,那么结束时间怎么求?倒过来再遍历一遍就好了,开始作为结束,结束作为开始,这样两者相减就是每台机器的工作时间,全加在一起就是答案

解法二:
首先按照产品的开始时间进行排序,然后我们把结束时间multiset里面没如果能够在这个里面使用upper_bound()找开始时间,如果返回的迭代值和.begin()相同的话,我们就把结束时间放入容器中。如果不相同的话,就把迭代值减一,开始时间就应该放入连在当前的迭代值后面,然后删除这个迭代值再在容器中插入结束时间。在处理的时候计算一下总和就可以了。
 
AC代码:
解法一:
 1 #include <iostream>
 2 #include<bits/stdc++.h>
 3 #define ll long long
 4 using namespace std;
 5 struct node
 6 {
 7     int data,flag;
 8 }a[200005];
 9 int s[100005],e[100005];
10 int cmp(node &a,node &b)
11 {
12     if(a.data<b.data||a.data==b.data&&a.flag<b.flag)
13         return 1;
14     else
15         return 0;
16 }
17 int main()
18 {
19     int n,t;
20     scanf("%d",&t);
21     while(t--)
22     {
23         scanf("%d",&n);
24         int x,y;
25         for(int i=0;i<n;i++)
26         {
27             scanf("%d%d",&x,&y);
28             a[i*2].data=x;
29             a[i*2].flag=1;
30             a[i*2+1].data=y;
31             a[i*2+1].flag=-1;
32         }
33         sort(a,a+n*2,cmp);
34 //        for(int i=0;i<n*2;i++)
35 //            printf("%d %d\n",a[i].data,a[i].flag);
36         long long tmp=0,sum=0;
37         for(int i=0;i<n*2;i++)
38         {
39             sum+=a[i].flag;
40             if(sum>tmp)
41             {
42                 s[sum]=a[i].data;
43                 tmp=sum;
44             }
45             tmp=max(tmp,sum);
46         }
47         sum=0,tmp=0;
48         for(int i=n*2-1;i>=0;i--)
49         {
50             sum-=a[i].flag;
51             if(sum>tmp)
52             {
53                 e[sum]=a[i].data;
54                 tmp=sum;
55             }
56             tmp=max(tmp,sum);
57         }
58         sum=0;
59         for(int i=1;i<=tmp;i++)
60         {
61             //printf("%d %d\n",e[i],s[i]);
62             sum=sum+(e[i]-s[i]);
63         }
64         printf("%lld %lld\n",tmp,sum);
65     }
66     return 0;
67 }
View Code

 

解法二:

 1 #include <iostream>
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 typedef long long ll;
 5 struct node
 6 {
 7     int s,e;
 8 }a[100005];
 9 int cmp(const node &a,const node &b)
10 {
11     if(a.s!=b.s)
12     return a.s<b.s;
13     else
14     return a.e<b.e;
15 }
16 int main()
17 {
18     int t,n;
19     scanf("%d",&t);
20     while(t--)
21     {
22         scanf("%d",&n);
23         for(int i=0;i<n;i++)
24         scanf("%d%d",&a[i].s,&a[i].e);
25         multiset<int>mset;
26         multiset<int>::iterator ite;
27         sort(a,a+n,cmp);
28         ll sum=0;
29         int ans=0;
30         mset.clear();
31         for(int i=0;i<n;i++)
32         {
33             ite=mset.upper_bound(a[i].s);
34             if(ite==mset.begin())
35             {
36                 //printf("%d==============\n",i);
37                 ans++;
38                 sum+=a[i].e-a[i].s;
39                 mset.insert(a[i].e);
40             }
41             else
42             {
43                 ite--;
44                 sum+=(a[i].e-*ite);
45                 mset.erase(ite);
46                 mset.insert(a[i].e);
47             }
48         }
49         printf("%d ",ans);
50         printf("%lld\n",sum);
51     }
52     return 0;
53 }
View Code

 

 
posted @ 2017-08-25 14:59  Wally的博客  阅读(316)  评论(0编辑  收藏  举报