The Fair Nut and Rectangles
题解
好板一dp
很明显的一道斜率优化,因为矩阵间不含包含关系,所以当时,一定有。
于是我们先根据数组从小到大排序,得到序列的值一定单调下降的。
很明显可以dp了,令为选择第个矩形且其它所有已选矩形的值都比其小时,最大的价值和。转移方程式易得:
鉴于,的时间复杂度明显过不了此题,考虑优化。
对于点,如果点比点更优,这有
。
明显可以通过斜率来优化。时间复杂度。
源码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000005
typedef long long LL;
typedef pair<int,int> pii;
const LL mo=1e9+7;
const LL INF=0x7f7f7f7f;
template<typename _T>
_T Fabs(_T x){return x<0?-x:x;}
LL n,dp[MAXN],ans;
LL head,tail,q[MAXN];
struct ming{LL x,y,a;}s[MAXN];
bool cmp(ming x,ming y){return x.x<y.x;}
double slope(int x,int y){
if(s[x].x==s[y].x)return INF;
return 1.0*(dp[x]-dp[y])/(s[x].x-s[y].x);
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++)
scanf("%lld %lld %lld",&s[i].x,&s[i].y,&s[i].a);
sort(s+1,s+n+1,cmp);
for(int i=1;i<=n;i++){
while(head+1<tail&&slope(q[head],q[head+1])>=s[i].y)head++;
dp[i]=s[i].x*s[i].y-s[i].a;
if(head<tail)dp[i]=max(dp[i],dp[q[head]]+1ll*(s[i].x-s[q[head]].x)*s[i].y-s[i].a);
while(head+1<tail&&slope(q[tail-2],q[tail-1])<=slope(q[tail-1],i))tail--;q[tail++]=i;
}
for(int i=1;i<=n;i++)ans=max(ans,dp[i]);
printf("%lld\n",ans);
return 0;
}