zoukankan      html  css  js  c++  java
  • Problem 2726. -- [SDOI2012]任务安排

    题意

    F.A.Qs Home Discuss ProblemSet Status Ranklist Contest 入门OJ ModifyUser   autointLogout 捐赠本站
    Problem 2726. -- [SDOI2012]任务安排

    2726: [SDOI2012]任务安排

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2742  Solved: 866
    [Submit][Status][Discuss]

    Description

    机器上有N个需要处理的任务,它们构成了一个序列。这些任务被标号为1到N,因此序列的排列为1,2,3...N。这N个任务被分成若干批,每批包含相邻的若干任务。从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti。在每批任务开始前,机器需要启动时间S,而完成这批任务所需的时间是各个任务需要时间的总和。注意,同一批任务将在同一时刻完成。每个任务的费用是它的完成时刻乘以一个费用系数Fi。请确定一个分组方案,使得总费用最小。

    Input

    第一行两个整数,N,S。
    接下来N行每行两个整数,Ti,Fi。

    Output

    一个整数,为所求的答案。

    Sample Input

    5 1
    1 3
    3 2
    4 3
    2 3
    1 4

    Sample Output

    153

    HINT

    Source

    [Submit][Status][Discuss]
    
    HOME Back
    [1, 4] 0<N<=1000 0<=S<=2^8 0<=Ti<=2^8 0<=Fi<=2^8
    [5, 12] 0<N<=300000 0<=S<=2^8 0<=Ti<=2^8 0<=Fi<=2^8
    [13, 20] 0<N<=100000 0<=S<=2^8 -(2^8)<=Ti<=2^80<=Fi<=2^8

    分析

    复习了一下斜率DP。并且学会了用函数思想来分析。

    [F[i]=min_{0le j<i}{F[j]+sumT[i]*(sumC[i]-sumC[j])+S*(sumC[N]-sumC[j])} ]

    这里的转移用了名为“费用提前计算”的经典思想。

    变化得到一次函数:

    [F[j]=(S+sumT[i])*sumC[j]+F[i]-sumT[i]*sumC[i]-S*sumC[N] ]

    显然是要在((sumC[j],F[j]))组成的点的平面中找一条斜率为(S+sumT[i])的直线过这些点中的一个,使得截距最小。

    (sumC[j],F[j])单调递增,维护下凸包即可。但是由于这题有负时间,所以要在单调队列上二分。

    时间复杂度(O(nlog n))

    代码

    #include<bits/stdc++.h>
    #define rg register
    #define il inline
    #define co const
    template<class T>il T read(){
        rg T data=0,w=1;rg char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') w=-1;ch=getchar();}
        while(isdigit(ch)) data=data*10+ch-'0',ch=getchar();
        return data*w;
    }
    template<class T>il T read(rg T&x) {return x=read<T>();}
    typedef long long ll;
    
    co int N=3e5+1;
    ll sumt[N],sumc[N],f[N];
    int q[N],n,s,l,r;
    int binary_search(int i,int k){
    	if(l==r) return q[l];
    	int L=l,R=r;
    	while(L<R){
    		int mid=L+R>>1;
    		if(f[q[mid+1]]-f[q[mid]]<=k*(sumc[q[mid+1]]-sumc[q[mid]])) L=mid+1;
    		else R=mid;
    	}
    	return q[L];
    }
    int main(){
    	read(n),read(s);
    	for(int i=1;i<=n;++i)
    		sumt[i]=sumt[i-1]+read<int>(),sumc[i]=sumc[i-1]+read<int>();
    	l=r=1,q[1]=0;
    	for(int i=1;i<=n;++i){
    		int p=binary_search(i,s+sumt[i]);
    		f[i]=f[p]-(s+sumt[i])*sumc[p]+sumt[i]*sumc[i]+s*sumc[n];
    		while(l<r&&(f[q[r]]-f[q[r-1]])*(sumc[i]-sumc[q[r]])>=(f[i]-f[q[r]])*(sumc[q[r]]-sumc[q[r-1]])) --r;
    		q[++r]=i;
    	}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    颜色混合openglglBlendFunc函数
    Types of Maps
    ogre 检测显卡gpu支持参数
    (转载)lua和c/c++互相调用实例分析
    光照模型
    阴影(转载)
    eval()解析JSON
    android中The connection to adb is down,问题和解决 AndroidEclipseAntXML
    比较android中的像素单位dp、px、pt、sp
    区别:DOM Core 与 HTMLDOM
  • 原文地址:https://www.cnblogs.com/autoint/p/10732903.html
Copyright © 2011-2022 走看看