状态是一维的而转移是二维的所以用斜率优化DP
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1e6+5;
long long f[maxn],g[maxn],w[maxn],x[maxn],a[maxn],b[maxn],c[maxn];
int begin=1,end=0;
int q[maxn];
int n;
int delta(int i,int j)
{
return x[j]*(a[j]-a[i-1])-b[j]+b[i-1];
}
double k(int i,int j)
{
return ((double)((f[j-1]+b[j-1])-(f[i-1]+b[i-1])))/((double)(a[j-1]-a[i-1]));
}
int main()
{
scanf("%d\n",&n);
for (int i=1;i<=n;i++)
{
scanf("%lld%lld%lld",&x[i],&w[i],&c[i]);
b[i]=b[i-1]+x[i]*w[i];
a[i]=a[i-1]+w[i];
}
for (int i=1;i<=n;i++)
{
while (begin<end&&(k(g[end-1],i)<k(g[end-1],g[end])))
end--;
g[++end]=i;
while (begin<end&&(k(g[begin],g[begin+1])<x[i]))
begin++;
//g[++end]=i;
f[i]=f[g[begin]-1]+x[i]*a[i]-x[i]*a[g[begin]-1]-b[i]+b[g[begin]-1]+c[i];
}
printf("%lld\n",f[n]);
}