羅区P2365のタスクのスケジューリング

\(\大F [I] = {\分\ limits_ {0 \ルJ <I}} \左(F [J] + \和\ limits_ {k = 1} ^ IT [K] * \和\ limits_ {K = J + 1} ^のiC [I] + S * \和\ limits_ {K = J + 1} ^ N C [K] \右)\)

\(\大F [I] = \分\ limits_ {0 \ルJ <I} \左(F [J] + ST [I] *(SC [I] -sC [J])+ Sの*(SC [n]は-sC [J])\右)\)

\(O(n^2)\)

決定ポイント考えてみましょう\(j個の\を)

\(\大F [I] = \左(F [J] + ST [I] *(SC [I] -sC [J])+ Sの*(SC [n]は-sC [J])\右) \)

\(\大F [J] =(ST [I] + S)* sCが[J] + F [i]は-sT [I] * sCが[I] -S * sCが[N] \)

\(\大Y = AX + B \)

インターセプト最小化\を(bは\)

凸包を維持

ので(、X \)\単調増加、単調にキューを維持することができます

/*
@Date    : 2019-08-15 19:13:10
@Author  : Adscn ([email protected])
@Link    : https://www.cnblogs.com/LLCSBlog
*/
#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define RG register
#define gi getint()
#define gc getchar()
#define File(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
IL int getint()
{
    RG int xi=0;
    RG char ch=gc;
    bool f=0;
    while(ch<'0'||ch>'9')ch=='-'?f=1:f,ch=gc;
    while(ch>='0'&&ch<='9')xi=(xi<<1)+(xi<<3)+ch-48,ch=gc;
    return f?-xi:xi;
}
template<typename T>
IL void pi(T k,char ch=0)
{
    if(k<0)k=-k,putchar('-');
    if(k>=10)pi(k/10,0);
    putchar(k%10+'0');
    if(ch)putchar(ch);
}
const int N=5007;
int f[N],t[N],c[N],n,S;
int main(void)
{
    n=gi,S=gi;
    for(int i=1;i<=n;++i)t[i]=gi+t[i-1],c[i]=gi+c[i-1];
    memset(f,63,sizeof f);
    f[0]=0;
    static int Q[N],l,r;
    for(int i=1;i<=n;++i)
    {
        while(l<r&&(f[Q[l+1]]-f[Q[l]])<=(c[Q[l+1]]-c[Q[l]])*(t[i]+S))++l;
        int j=Q[l];
        f[i]=f[j]+t[i]*(c[i]-c[j])+S*(c[n]-c[j]);
        while(l<r&&(f[i]-f[Q[r]])*(c[Q[r]]-c[Q[r-1]])<=(f[Q[r]]-f[Q[r-1]])*(c[i]-c[Q[r]]))--r;
        Q[++r]=i;
    }
    cout<<f[n];
    return 0;
}

おすすめ

転載: www.cnblogs.com/LLCSBlog/p/11360179.html