题目:
我是超链接
题解:
这道题是下凸壳+斜率dp的标准姿势呀
先将矩形按照x排序,再将后者比自己的y大的舍去(可以被另一个矩形完全包括),这样我们获得了长度单增,宽度单减的矩阵列
f[i]=min(f[j]+p[i]*q[j+1]);
K(q[j+1])>0且单调递减,这样我们获得了一个向下贴边的下凸壳
此时判断是否覆盖直线也要注意,因为大了的要撤走了哦
代码:
#include <cstdio>
#include <algorithm>
#define LL long long
using namespace std;
struct hh{int x,y;}a[50005];
int q[50005],p[50005],que[50005];LL f[50005];
int cmp(hh a,hh b){if (a.x==b.x) return a.y<b.y;else return a.x<b.x;}
LL K(int j){return q[j+1];}
LL B(int j){return f[j];}
LL Y(int i,int j){return (LL)(p[i]*K(j)+B(j));}
bool fg(int x1,int x2,int x3)
{
LL w1=(K(x1)-K(x2))*(B(x3)-B(x1));
LL w2=(K(x1)-K(x3))*(B(x2)-B(x1));
return w1<=w2;
}
int main()
{
int n,i;
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+n+1,cmp);
int cnt=0;
for (i=1;i<=n;i++)
{
while (cnt && a[i].y>=q[cnt]) cnt--;
q[++cnt]=a[i].y; p[cnt]=a[i].x;
}
int l,r;
l=r=0;
for (i=1;i<=cnt;i++)
{
while (l<r && Y(i,que[l])>=Y(i,que[l+1])) l++;
f[i]=Y(i,que[l]);
while (l<r && fg(i,que[r-1],que[r])) r--;
que[++r]=i;
}
printf("%lld",f[cnt]);
}