一本通 任务安排2 题解

题目传送门

斜率优化模板,没什么好说的,如果不会斜率优化请戳这里

原谅我水了一篇博客

当然注释还是会有的。

因为被卡了精度,所以需要把算斜率的公式变化一下,把除法移到另一边变成乘法即可。

代码如下:

#include <cstdio>
#include <cstring>
#define maxn 300010

int n,s;
int f[maxn],t[maxn],c[maxn];
int q[maxn],st(1),ed(1);
inline int up(int x,int y){return f[x]-f[y];}
inline int down(int x,int y){return c[x]-c[y];}
inline int calc(int x,int now){return f[x]+t[now]*(c[now]-c[x])+s*(c[n]-c[x]);}

int main()
{
	scanf("%d %d",&n,&s);
	for(int i=1;i<=n;i++)
	scanf("%d %d",&t[i],&c[i]),t[i]+=t[i-1],c[i]+=c[i-1];
	for(int i=1;i<=n;i++)
	{
		while(st<ed&&up(q[st+1],q[st])<(t[i]+s)*down(q[st+1],q[st]))st++;
//假如队列里面还有超过一个并且队首的两个的斜率比t[i]+s要小,那么q[st+1]肯定比q[st]要优,于是把q[st]踢掉
		f[i]=calc(q[st],i);//计算当前这一位的值
		while(st<ed&&up(q[ed],q[ed-1])*down(i,q[ed])>up(i,q[ed])*down(q[ed],q[ed-1]))ed--;
		//因为要维护下凸包,所以斜率要递增,假如当前点i和队尾的斜率比队尾两个点的斜率要小
		//那么此时不能将点i插入到队尾,那么就需要把此时的队尾踢掉
		q[++ed]=i;
	}
	printf("%d",f[n]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值