题目描述
给出n块土地,第i块长度为
解题分析
首先对于一块土地i,如果存在另一块土地j,有
然后发现是线性DP,
然后就直接套模板就行了。
#include<cstdio>
#include<algorithm>
#define LL long long
using namespace std;
struct data{
int x,y;
bool operator < (const data b)const{
return x>b.x||(x==b.x&&y>b.y);
}
}a[50005];
int n,m,que[50005],hed,til;
LL f[50005];
inline void readi(int &x){
x=0; char ch=getchar();
while ('0'>ch||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
}
LL getX(const int i,const int j){return a[i+1].x-a[j+1].x;}
LL getY(const int i,const int j){return f[j]-f[i];}
int main()
{
freopen("buy.in","r",stdin);
freopen("buy.out","w",stdout);
readi(m); n=hed=til=0;
for (int i=1;i<=m;i++) {readi(a[i].x); readi(a[i].y);} sort(a+1,a+m+1);
for (int i=1,mx=0;i<=m;i++) if (mx<a[i].y) {mx=a[i].y; a[++n]=a[i];}
hed=til=1; que[1]=f[0]=0;
for (int i=1;i<=n;i++){
while (hed<til&&getY(que[hed],que[hed+1])<=getX(que[hed],que[hed+1])*a[i].y) hed++;
f[i]=f[que[hed]]+(LL)a[i].y*a[que[hed]+1].x;
while (hed<til&&getY(que[til-1],que[til])*getX(que[til],i)>=getX(que[til-1],que[til])*getY(que[til],i)) til--;
que[++til]=i;
}
printf("%lld\n",f[n]);
return 0;
}