题目
参考任务安排1和任务安排2,还有一点 − 512 < T [ i ] < 512 -512<T[i]<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]);
}

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

被折叠的 条评论
为什么被折叠?



