解法
首先可以觀察到所有矩形排成了類似樓梯的形狀,所以如果對x排序,y也是有序的。
先按x從小到大排序
然後考慮dp:
轉移:
考慮優化這個dp:
這個轉移式中:只有這一項與i,j都有關,然後又因爲y[i]具有單調性,所以可以考慮斜率優化:
我們觀察和j有關的項,可以認爲,然後考慮斜率優化:如果隊頭和隊頭+1的兩條直線交點的橫座標小於y[i](我們在斜率優化的時候建出的座標系橫座標是y[i]),就把隊頭彈走,隊尾的處理也差不多。
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=1e6+5;
inline int read(){
char c=getchar();int t=0,f=1;
while((!isdigit(c))&&(c!=EOF)){if(c=='-')f=-1;c=getchar();}
while((isdigit(c))&&(c!=EOF)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
return t*f;
}
int n;
int dp[maxn];
struct node{
int x,y,a;
}p[maxn];
int h,t;
bool cmp(node a,node b){
return a.x<b.x;
}
inline double slope(int l,int r){
return 1.0*(dp[r]-dp[l])/(p[r].x-p[l].x);
}
int q[maxn];
signed main(){
n=read();
for(int i=1;i<=n;i++){
p[i].x=read(),p[i].y=read(),p[i].a=read();
}
sort(p+1,p+1+n,cmp);
h=t=1;
for(int i=1;i<=n;i++){
while(h+1<=t&&slope(q[h],q[h+1])>=p[i].y)h++;
int j=q[h];
dp[i]=max(dp[i-1],dp[j]+(p[i].x-p[j].x)*p[i].y-p[i].a);
while(h+1<=t&&slope(q[t-1],q[t])<=slope(q[t],i))t--;
q[++t]=i;
}
printf("%lld\n",dp[n]);
return 0;
}