poj 1180 Batch Scheduling (slope optimization)

Batch Scheduling



\(solution:\)

This should be the slope of the optimization of the most classic one subject, although one has written before \ (catstransport \) is the solution of the problem, but still look back at it, in fact, this question is harder than that one, but \ (catstransport \) is difficult to find the best formula code code.

First, monotonous queue optimization is used to optimize the transfer equation, there are some which only one relationship decisions alone or enumeration of the current state of the item and dynamic programming, and our slope optimization is used to optimize the transfer of some equations exist inside and enumeration of decision-making and have a direct bearing on the current status of items of dynamic programming (of course also need to optimize the slope of this item, with the enumeration of monotonic).

We first analyze the question head, to some tasks in order processing batches, the same batch share a time weight, it takes time before each batch pretreatment. Because it takes processed in chronological order, so we can expect a linear DP, and optimality subtasks that can be generalized to the whole situation. One might argue that restrictions will last a aftereffect, but in fact it is very easy to eliminate, we subtract an additional cost to all subsequent tasks because of delays in the pre-produced as long as each batch transfers. We list the transfer equation:

Because the topic did not say be sure to divide these tasks into a batch number, so we can directly set \ (F [i] \) said it would spend a minimum of $ i $ after the previous sub-division of tasks completed, and then pretreated at the time of our and the prefix \ (T [i] \) prefix and also the cost of the \ (S [i] \) and then transferred can be:

\(F[i]=^{min}_{0\leq k<j}\{F[j]+S\times (S[N]-S[j])+T[i]\times (S[i]-S[j]) \}\)

这个式子是 \(n^2\) 的复杂度,数据范围再次对我们说不,我们还要在优化:将与 $ j $ 无关的数提取出来,并去掉括号:

$F[i]=^{min}_{0\leq k<j}{F[j]+S\times S[N]-S\times S[j]+T[i]\times S[i]-T[i]\times S[j] } $

\(F[i]=^{min}_{0\leq k<j}\{F[j]-S\times S[j]-T[i]\times S[j] \}+S\times S[N]+T[i]\times S[i]\)

然后我们发现 \(max\) 函数里有与枚举的决策 $ j $ 和当前状态 $ i $ 都有直接关系的项\(T[i]\times S[j]\) )而且 \(T[i]\) 是单调递增的,于是我们就可以用斜率优化了。将 \(S[j]\) 最为 \(x\) 轴,将 $F[i]+S\times S[j] $ 作为 \(y\) 轴,然后每一个决策集合(我们所有的可以用的 \(j\) 都变成一个点),我们知道 \(T[i]\) (斜率)是单调递增的,所以只要这些点的的下凸壳即可!



\(code:\)

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

#define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int

using namespace std;

int n,s,sr=1;
ll v[300005];
ll t[300005];
ll f[300005];
ll q[300005];

inline int qr(){
    register char ch; register bool sign=0; rg res=0;
    while(!isdigit(ch=getchar())) if(ch=='-')sign=1;
    while(isdigit(ch)) res=res*10+(ch^48),ch=getchar();
    return sign?-res:res;
}

inline int get(int k){
    if(sr<2)return q[sr];
    rg l=1,r=sr-1,mid;
    while(l<=r){
        mid=(l+r)>>1;
        if(f[q[mid+1]]-f[q[mid]]<k*(v[q[mid+1]]-v[q[mid]]))l=mid+1;
        else r=mid-1;
    }return q[l];
}

int main(){
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    n=qr(); s=qr();
    for(rg i=1;i<=n;++i){
        t[i]=t[i-1]+qr();
        v[i]=v[i-1]+qr();
    } q[1]=0;
    for(rg i=1;i<=n;++i){
        rg j=get(s+t[i]);
        f[i]=f[j]-(s+t[i])*v[j]+v[i]*t[i]+s*v[n];
        while(sr>1&&(f[i]-f[q[sr]])*(v[q[sr]]-v[q[sr-1]])<=(f[q[sr]]-f[q[sr-1]])*(v[i]-v[q[sr]])) --sr;
        q[++sr]=i;
    }printf("%lld\n",f[n]);
    return 0;
}

Guess you like

Origin www.cnblogs.com/812-xiao-wen/p/11004627.html