bzoj 2153

/*那天我们说随机一道2开头的题,随机了很多权限题,然后就随机到了这道;
当时我还不会斜率优化 所以不会qaq;
昨天学了斜率优化_dafahao,突然懂了;
c[i]=∑t[i],s[i]=∑t[i]*i;
于是dp[i]=m+min(dp[j+1]+s[j]-s[i]-i*(c[j]-c[i]));(在i处强行建车站 最后到0处减去m就可以辣(╯‵□′)╯︵┻━┻)
然后考虑斜率优化 设j比k更优;
有dp[j+1]+s[j]-i*c[j]<dp[k+1]+s[k]-i*c[k];
令y[i]=dp[i+1]+s[i]有 y[j]-y[k]<i*(c[j]-c[k])然后就随便搞一搞就出来了;
要不我们再随机一道wsq嘛qaq;
今天下午打ACM,%司机,%白爷爷,%yj秋;
				By——WXH
P.S.我的程序跑了2000+ms,榜上200+ms的怎么跑的qaq*/
 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>

using namespace std;

typedef long long LL;

const int maxn=1000010;

int n,m,q[maxn],mx,head,tail;
LL dp[maxn],y[maxn],c[maxn],s[maxn],t[maxn];

int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) 
	{
		int pos,val;
		scanf("%d%d",&pos,&val);
		mx=max(mx,pos);
		t[pos]+=val;
	}
	for(int i=1;i<=mx;i++)
	{
		c[i]=c[i-1]+t[i];
		s[i]=s[i-1]+t[i]*i;
	}
	dp[mx]=m;
	head=tail=1;
	q[1]=mx;
	y[mx]=s[mx];
	for(int i=mx-1;i>=0;i--)
	{
		while(head<tail&&y[q[head+1]]-y[q[head]]<i*(c[q[head+1]]-c[q[head]]))
			head++;
		dp[i]=dp[q[head]+1]+s[q[head]]-s[i]-(c[q[head]]-c[i])*i+m;
		y[i]=dp[i+1]+s[i];
		while(head<tail&&(y[q[tail]]-y[q[tail-1]])*(c[i]-c[q[tail]])<=(y[i]-y[q[tail]])*(c[q[tail]]-c[q[tail-1]]))
			tail--;
		q[++tail]=i;
	}
	printf("%lld",dp[0]-m);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值