【dp】【斜率优化】土地购买

探讨农夫John如何通过最优策略购买N块长方形土地以节省总费用。介绍了几种算法思路,包括O(n^3)、O(n^2)和最终的O(n)最优算法,展示了如何通过斜率优化实现高效求解。

题目:

农夫John准备扩大他的农场,他正在考虑N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <
= 1,000,000; 1 <= 长 <= 1,000,000). 每块土地的价格是它的面积,但FJ可以同时购买多快土地. 这些土地的价
格是它们最大的长乘以它们最大的宽, 但是土地的长宽不能交换. 如果FJ买一块3x5的地和一块5x3的地,则他需要
付5x5=25. FJ希望买下所有的土地,但是他发现分组来买这些土地可以节省经费. 他需要你帮助他找到最小的经费.

题解:

零.

乱序,乱跑.
没有任何思路洗洗睡吧

O(1)O(1)O(1)最强算法rand()

(:逃

一.

以x为第一关键字排序,就只用(线性)顺序跑了
f[i]=min(f[j]+max(y[k])×x[i])(j+1≤k≤i)f[i]=min(f[j]+max(y[k])\times x[i])(j+1\leq k\leq i)f[i]=min(f[j]+max(y[k])×x[i])(j+1ki)

O(n3)O(n^3)O(n3)爆炸

二.

找规律发现有些点绝对不会作为max点
什么点,x,y都比至少一个别人小的点
那我怎么知道哪些点是满足的?
在这里插入图片描述
大概把点转移在图中,(秘籍·大眼观察法)发现维护一个下降的y,其他的丢掉就行了。
脑补一下,x已经前面比后面小了,要是y还比后面小,那就没面子了,还不如去死呢。。
然后min(y[k])−>y[j+1]min(y[k])->y[j+1]min(y[k])>y[j+1]

O(n2)O(n^2)O(n2)但还是不行

三.

f[i]=f[j]+y[j+1]×x[i]f[i]=f[j]+y[j+1]\times x[i]f[i]=f[j]+y[j+1]×x[i]
模版:fi=ai×fj+bi×gjf_i=a_i\times f_j+b_i\times g_jfi=ai×fj+bi×gj
非常简单的 斜率优化

O(n)O(n)O(n) OK走人

//没找到评测系统,未评测,未知正确性
#include<bits/stdc++.h>
#define ll long long
#define X(x) b[x+1].y
#define Y(x) dp[x]
using namespace std;
const int N=5e4+10,INF=1e9;
int n;
struct qw{
	int x,y;
	bool operator < (const qw a)const{return x==a.x?y<a.y:x<a.x;}
}a[N],b[N];
int p;
int dp[N];
int z[N],p1=1,p2=1;
double kt(int i,int j)
{
	return (double)(Y(i)-Y(j))/(double)(X(i)-X(j));
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	scanf("%d%d",&a[i].x,&a[i].y);
	sort(a+1,a+n+1);
	b[0].y=INF;
	for(int i=1;i<=n;i++)
	{
		while(p&&b[p].y<a[i].y)p--;
		b[++p]=a[i];
	}
	//for(int i=1;i<=p;i++)printf("(%d,%d)\n",b[i].x,b[i].y);
	for(int i=1;i<=p;i++)
	{
		while(p1<p2&&kt(z[p1],z[p1+1])>1.0*(-b[i].x))p1++;
		int j=z[p1];
		dp[i]=dp[j]+b[i].x*b[j+1].y;
		while(p1<p2&&kt(z[p2-1],z[p2])>kt(z[p2],i))p2--;
		z[++p2]=i;
	}
	printf("%d",dp[p]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值