zoukankan      html  css  js  c++  java
  • 【贪心】hdu6180 Schedule

    题意:给你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
    ",ans,sum);
    	}
    	return 0;
    }
  • 相关阅读:
    __all__
    python内置函数
    qZnF新存马王至许观制两利各
    PHP中获取当前页面的完整URL
    DedeCms用tag调用全站相关文章
    dedecms如何利用tag来调取相关文章
    SQL Server TempDB
    SQL Server Pivot 隐藏group
    Rebind and Rewind in Execution Plans
    batch 数字进制的问题
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/7425428.html
Copyright © 2011-2022 走看看