Link
Solve
这道题是任务安排的强化版
弱化版:P2365 任务安排 题解
还采取弱化版的思路,斜率优化
和弱化版不同,这道题的(k)满足单调性但不满足严格单调性,(k0=(S+SF[i]))不满足单调性
于是用二分法找到最优解就好了
Code
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=3e5+5,INF=1<<30;
LL N,S,hed=1,til=0,Q[maxn],ST[maxn],SF[maxn],F[maxn];
inline int read(){
int ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-f;ch=getchar();}
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline LL X(LL j){return SF[j];}
inline LL Y(LL j){return F[j];}
inline long double calc(LL i,LL j){return X(j)==X(i)?(Y(j)>=Y(i)?INF:-INF):((long double)(Y(j)-Y(i))/(X(j)-X(i)));}
inline LL find(LL k0){
if(hed==til)return Q[hed];
LL L=hed,R=til,mid;
while(L<R){
mid=(R-L>>1)+L;LL i=Q[mid],j=Q[mid+1];
if(calc(i,j)<k0)L=mid+1;
else R=mid;
}
return Q[L];
}
int main(){
freopen("P5785.in","r",stdin);
freopen("P5785.out","w",stdout);
N=read();S=read();
for(int i=1;i<=N;i++)ST[i]=ST[i-1]+read(),SF[i]=SF[i-1]+read();
Q[++til]=0;
for(int i=1;i<=N;i++){
int j=find(S+ST[i]);
F[i]=F[j]+ST[i]*(SF[i]-SF[j])+S*(SF[N]-SF[j]);
while(hed<til&&calc(Q[til-1],Q[til])>=calc(Q[til-1],i))--til;
Q[++til]=i;
}
printf("%lld
",F[N]);
return 0;
}