[Explanations] luogu_P2120_ warehouse construction (foundation slope optimization

process:

$f[i]=min(f[j]+\sum_{k=j+1}^{i}p_{k}*(x_{i}-x_{k}))+c[i]$

令$sum[i]=\sum_{j=1}^{i}p_{k},sumx[i]=\sum_{j=1}^{i}p_{k}*x_{k}$

$f[i]=min(f[j]+(sum[i]-sum[j])*x[i]-(sumx[i]-sumx[j]))+c[i]$

If more than $ $ $ k $ J excellent

$f[j]+(sum[i]-sum[j])*x[i]-(sumx[i]-sumx[j])<=f[k]+(sum[i]-sum[k])*x[i]-(sumx[i]-sumx[k])$

$f[j]-f[k]<=(sum[j]-sum[k])*x[i]+sumx[k]-sumx[j]$

$\frac{f[j]-f[k]+sumx[j]-sumx[k]}{sum[j]-sum[k]}<=x[i]$

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=1e6+9;
int n,x[maxn],p[maxn],c[maxn];
ll s[maxn],sx[maxn],f[maxn];
//s[i]=sumpi sx[i]=sum(pi*xi)
//f[j]-f[k]+sx[i]-sx[k]<=x[i]*(s[j]-s[k])
int q[maxn];
inline ll up(int j,int k){
    return f[j]-f[k]+sx[j]-sx[k];
}
inline ll down(int j,int k){
    return s[j]-s[k];
}
inline ll dp(int i,int j){
    return f[j]+(s[i]-s[j])*x[i]-(sx[i]-sx[j])+c[i];
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d%d%d",&x[i],&p[i],&c[i]),s[i]=s[i-1]+p[i],sx[i]=sx[i-1]+(ll)p[i]*x[i];
    int head=1,tail=1;
    for(int i=1;i<=n;i++){
        while(head<tail && up(q[head+1],q[head])<=x[i]*down(q[head+1],q[head]))head++;
        f[i]=dp(i,q[head]);
        while(head<tail && up(i,q[tail])*down(q[tail],q[tail-1])<=up(q[tail],q[tail-1])*down(i,q[tail]))tail--;
        q[++tail]=i;
    }
    printf("%d",f[n]);
    
}

 

Guess you like

Origin www.cnblogs.com/superminivan/p/11299576.html