luogu P2900 [USACO08MAR]Land Acquisition G 斜率优化dp

#include<cstdio>
#include<algorithm>
#include<iostream> 
#define Calc(i,j) (f[j-1]-f[i-1])/(a[i].h-a[j].h)
using namespace std;
const int N=1e5+9;
int q[N];
double f[N],k[N];
struct Land
{
	int w,h;//结构体排序
	inline bool operator<( Land&x)const
	{
		return h>x.h||(h==x.h&&w>x.w);
	}
} a[N];
int main()
{
	int n;
	cin>>n;
	int i,h,t;
	for(i=1; i<=n; ++i)
		cin>>a[i].w>>a[i].h;
	//如果一块土地的宽和高(其实是蒟蒻把长方形立在了平面上)都比另一块要小,
	//那么肯定是直接并购
	//所以就要把这些无用的去掉

	//先按照h排序 从大到小
	sort(a+1,a+n+1);
	for(h=i=1; i<=n; ++i) //双指针扫描去除无用矩形
		if(a[h].w<a[i].w)
			a[++h]=a[i];
	n=h;
	for(h=i=1,t=0; i<=n; ++i)
	{
		while(h<t&&k[t-1]>=Calc(q[t],i))
			--t;
		k[t]=Calc(q[t],i);
		q[++t]=i;
		while(h<t&&k[h]<=a[i].w)
			++h;
		f[i]=(double)a[q[h]].h*a[i].w+f[q[h]-1];
	}
	printf("%.0lf\n",f[n]);
	return 0;
}
posted @ 2020-05-07 23:24  晴屿  阅读(82)  评论(0编辑  收藏  举报