洛谷P2900 [USACO08MAR]土地征用Land Acquisition

https://www.luogu.com.cn/problem/P2900

可以想到,我们只关注对答案有贡献的物品,那么对于一个物品的w和l都<=另一个,那么这个物品可以完全合并到另一个物品的组里面去,他不用背考虑。

于是我们按w从小到大第一关键字,l从大到小第二关键字,每个相同的w只取最大的,然后单调栈搞出个w从小到大,l从大到小的序列。

我们知道肯定是w越小的配l越大的比较好,所以肯定是这样顺序下连续的一段一段一组更优,接下来我们考虑如何将他们合并

dp[i]=min(w[i]*l[k]+dp[k-1]),表示前i个合并的最小值。

这个式子可以看出,对于每个i,w[i]恒定,l[k],dp[k-1]是之前求出来的一些点,要求dp[i]最小,很显然就是固定斜率,之前有很多点,斜率优化。

dp[k-1]=w[i]*(-l[k])+dp[i],我们以(-l[k])为横坐标,dp[k-1]为纵坐标,那么与y轴的焦点的值就是dp[i],我们希望dp[i]尽可能小。

(-l[k])递增,dp[k-1]递增,希望与y轴截距最小,通过画图分析,我们应该用单调队列维护一个斜率递增的序列.

#include<bits/stdc++.h>
using namespace std;

const int maxl=5e4+10;

int n,cnt,top;
long long ans;
long long dp[maxl];
struct node
{
	long long x,y;
}a[maxl],b[maxl],s[maxl];
__int128 t=1; 

inline bool cmp(const node &a,const node &b)
{
	if(a.x==b.x)
		return a.y>b.y;
	return a.x<b.x;
}

inline void prework()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%lld%lld",&a[i].x,&a[i].y);
	sort(a+1,a+1+n,cmp);
	int top=0;
	for(int i=1;i<=n;i++)
	{
		if(top>0 && a[i].x==s[top].x)
			continue;
		while(top>0 && s[top].y<=a[i].y)
			top--;
		s[++top]=a[i];
	}
	cnt=top;
	for(int i=1;i<=top;i++)
		b[i]=s[i];
}

inline long long calc(long long k,int id)
{
	return -k*s[id].x+s[id].y;
}

inline bool cmpk(node a,node b,node c)
{
	return t*(c.y-b.y)*(b.x-a.x)<=t*(b.y-a.y)*(c.x-b.x);
}

inline void mainwork()
{
	ans=0;int head=1,tail=0;node d;
	for(int i=1;i<=cnt;i++)
	{
		d=node{-b[i].y,dp[i-1]};
		while(head<tail && cmpk(s[tail-1],s[tail],d))
			tail--;
		s[++tail]=d;
		while(head<tail && calc(b[i].x,head)>=calc(b[i].x,head+1))
			head++;
		dp[i]=calc(b[i].x,head);
	}
}

inline void print()
{
	printf("%lld",dp[cnt]);
}

int main()
{
	prework();
	mainwork();
	print();
	return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值