题意:
题解:
首先可以知道,如果一个矩形包含另一个,那么另一个就没有存在的必要,所以先去重。
然后可以发现图就变成了这样
写一下方程:
d
p
[
i
]
=
m
i
n
(
d
p
[
j
]
+
w
[
i
]
∗
h
[
j
+
1
]
)
dp[i]=min(dp[j]+w[i]*h[j+1])
dp[i]=min(dp[j]+w[i]∗h[j+1])
然后w是递增的,所以依旧是一个开口向上的函数。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=5e4+5;
struct node{
ll w,h;
bool operator< (const node& a)const {
if(w==a.w)return h>a.h;
return w<a.w;
}
}p[N];
int st[N];
ll dp[N];
int main()
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld%lld",&p[i].w,&p[i].h);
sort(p+1,p+1+n);
int all=1;
for(int i=2;i<=n;i++){
while(all&&p[i].w>=p[all].w&&p[i].h>=p[all].h)all--;
p[++all]=p[i];
}
//p[all+1]={0,0};
int sta=0,en=0;
//dp[1]=p[1].h*p[1].w;
//st[++en]=1;
for(int i=1;i<=all;i++){
while(sta<en&&(dp[st[sta+1]]-dp[st[sta]])<(p[st[sta]+1].h-p[st[sta+1]+1].h)*p[i].w)sta++;
dp[i]=dp[st[sta]]+p[i].w*p[st[sta]+1].h;
while(sta<en&&(p[st[en]+1].h-p[st[en-1]+1].h)*(-dp[i]+dp[st[en]])<(p[i+1].h-p[st[en]+1].h)*(-dp[st[en]]+dp[st[en-1]]))en--;
st[++en]=i;
}
printf("%lld\n",dp[all]);
return 0;
}