[USACO08MAR]土地征用Land Acquisition

题面描述

传送门

思路

瞎扯

乍一看,貌似找不到什么有序的东西。

先排序吧(第一关键字为 x x x坐标,第二关键字为 y y y坐标,都以从小到大排序)。

类似下图

在这里插入图片描述

发现相邻的两块土地(排序后) i , i + 1 i,i+1 i,i+1,如果 y i &lt; y i + 1 y_i&lt;y_{i+1} yi<yi+1,那么买第 i + 1 i+1 i+1块土地,顺便可以带上第 i i i块土地(岂不美哉!,买一送一啊!),

按照这样的思想,我们可以买一送 n n n啊。

之后去掉送的土地,保留有用的(至于如何有用,详见上文)土地。

如下图

在这里插入图片描述
之后我们就可以愉快地推状态转移方程啦!

设离散化之后的数组为 b b b(保证 x x x坐标不下降)

F i = min ⁡ ( F j + y b j + 1 ∗ x b i ) F_i=\min(F_j+y_{b_{j+1}}*x_{b_i}) Fi=min(Fj+ybj+1xbi)

y b j + 1 y_{b_{j+1}} ybj+1保证是 b [ j + 1 , i ] b_{[j+1,i]} b[j+1,i]后最大的纵坐标哦,因为后面如果有比它大的纵坐标, b j + 1 b_{j+1} bj+1根本不存在于数组中。

证明决策单调性

设有
F k + y b k + 1 ∗ x b i ≤ F j + y b j + 1 ∗ x b i ( j &lt; k &lt; i ) F_k+y_{b_{k+1}}*x_{b_i}\le F_j+y_{b_{j+1}}*x_{b_i} (j&lt;k&lt;i) Fk+ybk+1xbiFj+ybj+1xbi(j<k<i)

证明:对于未来状态 t t t,都有

F k + y b k + 1 ∗ x b t ≤ F j + y b j + 1 ∗ x b t ( j &lt; k &lt; i &lt; t ) F_k+y_{b_{k+1}}*x_{b_t}\le F_j+y_{b_{j+1}}*x_{b_t}(j&lt;k&lt;i&lt;t) Fk+ybk+1xbtFj+ybj+1xbt(j<k<i<t)

由于 x b t , y b k + 1 , y b j + 1 x_{b_t},y_{b_{k+1}},y_{b_{j+1}} xbt,ybk+1,ybj+1不变,证毕。

这怕不是不用证明

踢队头

F k + y b k + 1 ∗ x b i ≤ F j + y b j + 1 ∗ x b i ( j &lt; k &lt; i ) F_k+y_{b_{k+1}}*x_{b_i}\le F_j+y_{b_{j+1}}*x_{b_i} (j&lt;k&lt;i) Fk+ybk+1xbiFj+ybj+1xbi(j<k<i)

F j − F k ≥ y b k + 1 ∗ x b i − y b j + 1 ∗ x b i F_j-F_k\ge y_{b_{k+1}}*x_{b_i}-y_{b_{j+1}}*x_{b_i} FjFkybk+1xbiybj+1xbi

y b k + 1 ≤ y b j + 1 y_{b_{k+1}}\le y_{b_{j+1}} ybk+1ybj+1可知,

F j − F k y b k + 1 − y b j + 1 ≤ x b i \frac{F_j-F_k}{y_{b_{k+1}}-y_{b_{j+1}}}\le x_{b_i} ybk+1ybj+1FjFkxbi

因此,当上述不等式成立时, k k k优于 j j j

如果 c a l c ( q h e a d , q t a i l ) = F h e a d − F h e a d + 1 y b h e a d + 1 − y b h e a d ≤ x b i calc(q_{head},q_{tail})=\frac{F_{head}-F_{head+1}}{y_{b_{head+1}}-y_{b_{head}}}\le x_{b_{i}} calc(qhead,qtail)=ybhead+1ybheadFheadFhead+1xbi

说明 h e a d + 1 head+1 head+1优于 h e a d head head

踢队尾

我们首先一定要确定 i i i这个状态,要优于 q t a i l q_{tail} qtail

要维护的队列由于 q t a i l − 1 q_{tail-1} qtail1一定优于 q t a i l q_{tail} qtail

现有一个标准值 x b t ( t a i l &lt; t ) x_{b_t}(tail&lt;t) xbt(tail<t)

c a l c ( q t a i l − 1 , q t a i l ) ≥ x b t calc(q_{tail-1},q_{tail)}\ge x_{b_t} calc(qtail1,qtail)xbt

如果 q t a i l q_{tail} qtail要优于 i i i

c a l c ( q t a i l , i ) ≥ c a l c ( q t a i l − 1 , q t a i l ) calc(q_{tail},i)\ge calc(q_{tail-1},q_{tail}) calc(qtail,i)calc(qtail1,qtail)

才能确保 q t a i l q_{tail} qtail优于 i i i

反之,当 c a l c ( q t a i l , i ) ≤ c a l c ( q t a i l − 1 , q t a i l ) calc(q_{tail},i)\le calc(q_{tail-1},q_{tail}) calc(qtail,i)calc(qtail1,qtail)时,需要删去队尾。

貌似就没了哦。

AC code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#define gc getchar()
#define ll long long 
using namespace std;
const int N=5e4+10;
inline void qr(ll &x)
{
	x=0;int f=1;char c=gc;
	while(c<'0'||c>'9')c=gc;
	while(c>='0'&&c<='9'){x=x*10+(c^48);c=gc;}
	x*=f;
}
void qw(ll x)
{
	if(x/10)qw(x/10);
	putchar(x%10+48);
}
struct node
{
	ll x,y;
}a[N];
bool cmp(node a,node b){return a.x==b.x?a.y<b.y:a.x<b.x;}
ll f[N];int b[N],q[N],l,r;
inline double calc(int j,int k){return (f[j]-f[k])/(double)(a[b[k+1]].y-a[b[j+1]].y);}
int main()
{
	int n;scanf("%d",&n);
	for(int i=1;i<=n;i++)qr(a[i].x),qr(a[i].y);
	sort(a+1,a+n+1,cmp);
	int tot=0;
	for(int i=1;i<=n;i++)
	{
		while(tot&&a[b[tot]].y<=a[i].y)--tot;
		b[++tot]=i;
	}
	l=1;r=1;q[1]=0;
	for(int i=1;i<=tot;i++)
	{
		while(l<r&&calc(q[l],q[l+1])<=1.0*a[b[i]].x)++l;
		f[i]=f[q[l]]+a[b[i]].x*a[b[q[l]+1]].y;
		while(l<r&&calc(q[r],i)<=calc(q[r-1],q[r]))--r;
		q[++r]=i;
	}
	qw(f[tot]);puts("");
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值