[USACO08MAR]土地征用Land Acquisition

题面在这里

题意

约翰准备扩大他的农场,眼前他正在考虑购买N块长方形的土地。
如果约翰单买一块土地,价格就是土地的面积,但他可以选择并购一组土地,
并购的价格为这些土地中最大的长乘以最大的宽。
给定每份土地的尺寸,请你帮助他计算购买所有土地所需的最小费用。

数据范围

\[1 \le N \le 50000,1 \le width_i,length_i\le 10^6 \]

sol

我们发现,如果一块土地被另一块土地所包含(即长和宽都比另一块土地小),
那么只需购买那另一块土地即可,于是我们可以据此筛掉其他的土地,
只剩下一些长度递减,宽度递增的土地

然后我们猜想FJ每次购买的一组土地肯定是这个序列连续的一段
(假设某种最优方案中购买的土地不是一段,那么将中间的部分补上显然不会更劣)

于是就变成了经典的序列分段问题,
\(f[i]\)表示购买前\(i\)块土地所需的最小代价,我们有

\[f[i]=min_{j=0}^{i-1}(f[j]+length[j]\times width[i]) \]

斜率优化插点\((-length[j],f[j])\),按照递增的\(k=width[i]\)处理即可

代码

#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<iomanip>
#include<cstring>
#include<complex>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define mp make_pair
#define pb push_back
#define RG register
#define il inline
using namespace std;
typedef unsigned long long ull;
typedef vector<int>VI;
typedef long long ll;
typedef double dd;
const dd eps=1e-10;
const int mod=1e8;
const int N=50010;
il ll read(){
	RG ll data=0,w=1;RG char ch=getchar();
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch<='9'&&ch>='0')data=data*10+ch-48,ch=getchar();
	return data*w;
}

il void file(){
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
}

int n,m;ll f[N];
struct area{ll a,b;}s[N];
bool cmp(area x,area y){
	if(x.a==y.a)return x.b>y.b;
	else return x.a>y.a;
}

struct node{ll x,y;}Q[N];ll L=1,R;
il void insert(node q){
	while(L<R&&(Q[R].y-Q[R-1].y)*(q.x-Q[R].x)>(q.y-Q[R].y)*(Q[R].x-Q[R-1].x))R--;
	Q[++R]=q;
}
il ll query(ll k){
	while(L<R&&k*(Q[L+1].x-Q[L].x)>Q[L+1].y-Q[L].y)L++;
	return Q[L].y-Q[L].x*k;
}

int main()
{
	n=read();
	for(RG int i=1;i<=n;i++)s[i].a=read(),s[i].b=read();
	sort(s+1,s+n+1,cmp);
	for(RG int i=1;i<=n;i++)
		if(!m||s[i].a<s[m].a&&s[i].b>s[m].b)s[++m]=s[i];
	insert((node){-s[1].a,0});
	for(RG int i=1;i<=m;i++){
		f[i]=query(s[i].b);
		insert((node){-s[i+1].a,f[i]});
	}
	printf("%lld\n",f[m]);
	return 0;
}

posted @ 2018-03-25 17:33  cjfdf  阅读(211)  评论(0编辑  收藏  举报