#斜率优化,单调队列,动态规划,二分#bzoj 2726 任务安排3

本文介绍了一种利用二分法解决特定条件下的动态规划问题的方法。通过对任务序列的费用进行预处理,并借助于单调队列优化,实现了高效求解最优解的过程。

题目

参考任务安排1和任务安排2,还有一点 − 512 &lt; T [ i ] &lt; 512 -512&lt;T[i]&lt;512 512<T[i]<512


分析

由于 T T T的值改变了,所以 S + S U M T [ I ] S+SUMT[I] S+SUMT[I]就不再具有单调性,所以必须得用二分求出最优解


代码

#include <cstdio>
typedef long long ll; int n,s,q[300001];
ll f[300001],st[300001],sc[300001];
ll in(){
    ll ans=0; int f=1; char c=getchar();
    while ((c<48||c>57)&&c!='-') c=getchar();
    if (c=='-') c=getchar(),f=-f;
    while (c>47&&c<58) ans=ans*10+c-48,c=getchar();
    return ans*f;
}
int bs(int i,int k,int l,int r){
	if (l==r) return q[l];
	while (l<r){
		int mid=(l+r)>>1;
		if (f[q[mid+1]]-f[q[mid]]<=k*(sc[q[mid+1]]-sc[q[mid]])) l=mid+1;
		else r=mid;
	}
	return q[l];
}
int main(){
    n=in(); s=in(); q[1]=0;
    for (int i=1;i<=n;i++)
        st[i]=st[i-1]+in(),sc[i]=sc[i-1]+in();//费用提前计算
    f[0]=0; int l=1,r=1;
    for (int i=1;i<=n;i++){
    	int ans=bs(i,s+st[i],l,r);//二分求答案
        f[i]=f[ans]-(s+st[i])*sc[ans]+st[i]*sc[i]+s*sc[n];//动态规划
        while (l<r&&(f[q[r]]-f[q[r-1]])*(sc[i]-sc[q[r]])>=(f[i]-f[q[r]])*(sc[q[r]]-sc[q[r-1]])) r--;//队尾不满足单调递增
        q[++r]=i; 
    }
    return !printf("%lld",f[n]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值