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