對於100%的數據, N ≤1000000。 全部的Xi, Pi, Ci均在32位帶符號整數之內,保證中間計算結果不超過64位帶符號整數。 .net
因而最近我又開始刷BZOJ了……不過以我這水平也只能刷些水題……blog
又碰到了一個斜率優化dp……如今好像已經有點感受了,反正一維dp超級簡單複雜度又不對的題大多數都是斜率優化題。ip
一維方程你們應該都會……設fi表示在工廠i修倉庫的最小費用,每次轉移枚舉上一個倉庫在哪裏便可。get
這個斜率我已經不想推了……原諒我太懶了。網上寫的都很好,要看請戳這裏。WA了三發由於算斜率時沒有開double簡直差評……string
下面貼代碼:產品
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 1000010
using namespace std;
typedef long long llg;
struct data{
llg x,y;
}s[maxn];
int n,X[maxn],C[maxn],d[maxn],l,r;
llg s1[maxn],s2[maxn],f[maxn];
int getint(){
int w=0;bool q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=1;
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
}
long double xie(data x,data y){
if(x.x==y.x) return 1e100;
return (long double)(y.y-x.y)/(long double)(y.x-x.x);
}
int main(){
File("a");
n=getint();
for(int i=1,P;i<=n;i++){
X[i]=getint(); P=getint(); C[i]=getint();
s1[i]=s1[i-1]+P; s2[i]=s2[i-1]+(llg)X[i]*(llg)P;
}
for(int i=1;i<=n;i++){
while(l<r && xie(s[d[l]],s[d[l+1]])<=X[i]) l++;
f[i]=(llg)C[i]+f[d[l]]+(s1[i]-s1[d[l]])*(llg)X[i]-s2[i]+s2[d[l]];
s[i].x=s1[i]; s[i].y=f[i]+s2[i];
while(l<r && xie(s[d[r-1]],s[d[r]])>xie(s[d[r]],s[i])) r--;
d[++r]=i;
}
printf("%lld",f[n]);
}