洛谷P2365 任务安排

\(\large f[i]={\min\limits_{0\le j<i }}\left(f[j]+\sum\limits_{k=1}^iT[k]*\sum\limits_{k=j+1}^iC[i]+S*\sum\limits_{k=j+1}^n C[k]\right)\)

\(\large f[i]=\min\limits_{0\le j <i}\left(f[j]+sT[i]*(sC[i]-sC[j])+S*(sC[n]-sC[j])\right)\)

\(O(n^2)\)

考虑决策点\(j\)

\(\large f[i]=\left(f[j]+sT[i]*(sC[i]-sC[j])+S*(sC[n]-sC[j])\right)\)

\(\large f[j]=(sT[i]+S)*sC[j]+f[i]-sT[i]*sC[i]-S*sC[n]\)

\(\large y=ax+b\)

最小化截距\(b\)

维护下凸壳

因为\(a,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