[ZJOI2007] 仓库建设 - 斜率优化dp

大脑真是个很优秀的器官,做事情之前总会想着这太难,真的逼着自己做下去,回头看看,其实也不过如此

很朴素的斜率优化dp了

首先要读懂题目(我的理解能力好BUG啊)

然后设\(dp[i]\)表示处理完前\(i\)个家伙,并且在第\(i\)个家伙处建仓的答案

那么有

\[dp[i] = min_{j=1}^{i-1}\{dp[j] + \sum_{k=j+1}^{i-1} p[k] * (x[i] - x[k])\} + c[i]\]

化简发现,优劣比较条件为

\[\frac{dp[p]-dp[q]+t[p]-t[q]}{s[p]-s[q]} < x[i]\]

于是就皆大欢喜啦

#include 
using namespace std;

#define int long long
const int N = 1000005;

int n,x[N],p[N],c[N],s[N],t[N],f[N],q[N],l,r;

double slope(int k,int j) {
    return 1.0 * (f[j]+t[j]-f[k]-t[k]) / (s[j]-s[k]);
}

signed main() {
    scanf("%lld",&n);
    for(int i=1;i<=n;i++) {
        scanf("%lld%lld%lld",&x[i],&p[i],&c[i]);
        s[i]=s[i-1]+p[i];
        t[i]=t[i-1]+x[i]*p[i];
    }
    l=1; r=1;
    for(int i=1;i<=n;i++) {
        while(l= slope(q[r],i)) --r;
        q[++r]=i;
    }
    cout<

你可能感兴趣的:([ZJOI2007] 仓库建设 - 斜率优化dp)