【筆記】斜率優化dp
阿新 • • 發佈:2018-12-13
BZOJ 1096 倉庫建設
/* LittleFall : Hello! */
#include <bits/stdc++.h>
typedef long long ll;
using namespace std; inline int read();
const int M = 1000016, MOD = 1000000007;
ll X[M], P[M], C[M], sp[M], sxp[M];
ll dp[M];
inline double slope(int k, int j)
{
return double(dp[j]-dp[k]+sxp[j]-sxp[k])/double(sp[j]-sp[k] );
}
int q[M]; //雙端佇列
int main(void)
{
#ifdef _LITTLEFALL_
freopen("in.txt","r",stdin);
#endif
int n = read(), l=0, r=0;
for(int i=1;i<=n;++i)
{
X[i] = read(), P[i] = read(), C[i] = read();
sp[i] = sp[i-1] + P[i];
sxp[i] = sxp[i-1] + P[i]*X[i];
}
for(int i=1,t;i<=n;++i)
{
while (l<r && slope(q[l],q[l+1])<X[i]) l++; //pop_front
t = q[l];
dp[i] = C[i] + dp[t] - (sxp[i]-sxp[t]) + X[i]*(sp[i]-sp[t]);
while(l<r && slope(q[r-1],q[r])>slope(q[r],i)) r--; //pop_back
q[++r] = i; //push_back
}
cout << dp[n] << endl;
return 0;
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}