标签:turn names 机器 一个 include main sum poi eof
题意:给你n个任务的开始时间和结束时间,一个机器同时最多执行一个任务,问你最少要几个机器。保证机器最少的前提下,问你每个机器的开动时间(最后一次关闭-第一次开启)之和最少是多少。
把这些线段画在数轴上,最大的重叠数就是最少要几个机器。
开动时间怎么算呢?第i个机器的开动时间其实就是(再也不需要>=i台机器的第一个位置 - 需要>=i台机器的第一个位置)。对每个机器的这个值求和即可。
要先离散化。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; struct Point{ int p,v; }t[200005]; bool cmp(const Point &a,const Point &b) { return a.v<b.v; } int T,n; int xs[100005],ys[100005],a[200005],ma[200005],Left[200005],Right[200005]; int sufmax[200005]; int main(){ //freopen("1010.in","r",stdin); scanf("%d",&T); for(;T;--T){ memset(a,0,sizeof(a)); memset(ma,0,sizeof(ma)); memset(Left,0x7f,sizeof(Left)); memset(Right,0,sizeof(Right)); memset(sufmax,0,sizeof(sufmax)); int all=0; scanf("%d",&n); for(int i=1;i<=n;++i){ ++all; scanf("%d",&t[all].v); t[all].p=all; ++all; scanf("%d",&t[all].v); t[all].p=all; } sort(t+1,t+all+1,cmp); int zy=0; if(t[1].p%2==1){ xs[(t[1].p+1)/2]=++zy; } else{ ys[t[1].p/2]=++zy; } ma[zy]=t[1].v; for(int i=2;i<=all;++i){ if(t[i].v!=t[i-1].v){ ++zy; } if(t[i].p%2==1){ xs[(t[i].p+1)/2]=zy; } else{ ys[t[i].p/2]=zy; } ma[zy]=t[i].v; } for(int i=1;i<=n;++i){ ++a[xs[i]]; --a[ys[i]]; } for(int i=1;i<=zy;++i){ a[i]+=a[i-1]; } sufmax[zy]=a[zy]; for(int i=zy-1;i>=1;--i){ sufmax[i]=max(a[i],sufmax[i+1]); } int ans=*max_element(a+1,a+zy+1); for(int i=1;i<=zy;++i){ if(Left[a[i]]>2000000000){ Left[a[i]]=i; } } for(int i=ans-1;i>=1;--i){ Left[i]=min(Left[i],Left[i+1]); } for(int i=zy;i>=1;--i){ if(sufmax[i]!=sufmax[i-1]){ for(int j=sufmax[i]+1;j<=sufmax[i-1];++j){ Right[j]=i; } } } ll sum=0; for(int i=1;i<=ans;++i){ sum+=(ll)(ma[Right[i]]-ma[Left[i]]); } printf("%d %lld\n",ans,sum); } return 0; }
标签:turn names 机器 一个 include main sum poi eof
原文地址:http://www.cnblogs.com/autsky-jadek/p/7425428.html