【貪心】hdu6180 Schedule
阿新 • • 發佈:2017-08-24
set highlight log memset space else con scanf 開始
題意:給你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; }
【貪心】hdu6180 Schedule