本人采用逆天倒推法,从 n 逆推到 1,被 HACK,求调。
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define read read()
#define pt puts("")
inline int read{
int x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-'0',c=getchar();
return f*x;
}
void write(int x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
return;
}
const int N = 1e6+10;
int n;
int c[N],x[N],p[N],S[N];
int dp[N][2];
int q[N<<1],head,tail;
int to[N];
int SP[N],P[N];
double slope(int x,int y){
double a=((dp[x][1]-SP[x]+S[x]*P[x])-(dp[y][1]-SP[y]+S[y]*P[y]))*1.0;
double b=S[x]-S[y];
return a/b;
}
signed main(){
#ifndef ONLINE_JUDGE
freopen("lty.in","r",stdin);
freopen("lty.out","w",stdout);
#endif
n=read;
for(int i=1;i<=n;i++) S[i]=read,p[i]=read,c[i]=read;
for(int i=1;i<=n-1;i++) S[i]=S[n]-S[i];
S[n]=0;
for(int i=n;i>=1;i--) SP[i]=SP[i+1]+p[i]*S[i];
for(int i=n;i>=1;i--) P[i]=P[i+1]+p[i];
if(!P[1]){putchar('0');return 0;}
memset(dp,0x3f,sizeof(dp));
while(!p[n]) n--;
dp[n][1]=c[n];
head=1,tail=0;
q[++tail]=n;
for(int i=n-1;i>=1;i--){
dp[i][1]=min(dp[i+1][0],dp[i+1][1])+c[i];
while(head<tail && slope(q[head+1],q[head])<P[i]) head++;
int j=q[head];
dp[i][0]=dp[j][1]+SP[i]-SP[j]-S[j]*(P[i]-P[j]);
while(head<tail && slope(q[tail],q[tail-1])>=slope(i,q[tail])) tail--;
q[++tail]=i;
}
// for(int i=n-1;i>=1;i--){
// dp[i][1]=min(dp[i+1][0],dp[i+1][1])+c[i];
// for(int j=i+1;j<=n;j++){
// int tmp=0;
// for(int k=i;k<=j-1;k++) tmp+=p[k]*(S[k]-S[j]);
// dp[i][0]=min(dp[i][0],dp[j][1]+tmp);
// }
// }暴力代码,也是被hack
write(min(dp[1][0],dp[1][1]));
return 0;
}