LOJ 10189 仓库建设 ——斜率优化dp
题目:https://loj.ac/problem/10189
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define db double #define ll long long using namespace std; const int N=1e6+5; int n,d[N],p[N],C[N]; ll s[N],c[N],dp[N]; int q[N],he,tl; int rdn() { int ret=0;bool fx=1;char ch=getchar(); while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();} while(ch>='0'&&ch<='9') ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar(); return fx?ret:-ret; } ll Y(int a){return dp[a]+c[a]*d[a]-s[a];} db slp(int u,int v){return (db)(Y(v)-Y(u))/(d[v]-d[u]);} int main() { n=rdn(); for(int i=1;i<=n;i++) d[i]=rdn(),p[i]=rdn(),C[i]=rdn(); for(int i=1;i<=n;i++) d[i]=d[n]-d[i]; for(int i=n;i>=0;i--) c[i]+=c[i+1]+p[i],s[i]=s[i+1]+(ll)p[i]*d[i]; he=1;q[tl=1]=n;dp[n]=C[n]; for(int i=n-1;i>=0;i--) { while(he<tl&&slp(q[he],q[he+1])<=c[i+1])he++; int j=q[he]; dp[i]=dp[j]+c[j]*d[j]-s[j]-c[i+1]*d[j]+s[i+1]+C[i]; while(he<tl&&slp(q[tl-1],q[tl])>=slp(q[tl-1],i))tl--; q[++tl]=i; } printf("%lld\n",dp[0]); return 0; }