写的是斜率优化
其中 fi 表示车在第 i 秒出发的最小等待时间之和。
一直过不了,65pts
希望大佬能帮我调一调,谢谢!
#include<iostream>
using namespace std;
#define int long long
const int N=5e6;
int q[N],l,r,n,m,f[N],p[N],s[N],mt;
int X(int x){
return p[x];
}
int Y(int x){
return f[x]+s[x];
}
const int INF=0x7ffffffffffff;
long double slope(int x,int y){
if(X(x)==X(y))
return -INF;
return (Y(x)-Y(y))/(1.l*X(x)-X(y));
}
bool cross(int x,int y,int z){
return (Y(x)-Y(y))*(1.l*X(y)-X(z))>=(Y(y)-Y(z))*(1.l*X(x)-X(y));
}
int mi[N];
int read(){
int x=0;char c=0;
while(!isdigit(c))c=getchar();
while(isdigit(c))x=x*10+c-'0',c=getchar();
return x;
}
signed main(){
n=read(),m=read();
for(int x,i=1;i<=n;i++){
x=read();
p[x]+=1;
s[x]+=x;
mt=max(mt,x);
}
for(int i=1;i<=mt+m;i++)
p[i]+=p[i-1],s[i]+=s[i-1];
q[0]=l=r=0;
for(int i=1;i<=mt+m;i++){
if(i-m>0){
if(mi[X(i-m)]>Y(i-m)){
r--;
while(l<r&&cross(q[r-1],q[r],i-m))
r--;
q[++r]=i-m;
mi[X(i-m)]=Y(i-m);
}else if(mi[X(i-m+1)]==0){
while(l<r&&cross(q[r-1],q[r],i-m))
r--;
q[++r]=i-m;
mi[X(i-m)]=Y(i-m);
}
}
while(l<r&&slope(q[l],q[l+1])<i)
l++;
f[i]=f[q[l]]+(p[i]-p[q[l]])*i-(s[i]-s[q[l]]);
}
int ans=INF;
for(int i=mt;i<mt+m;i++)
ans=min(f[i],ans);
cout<<ans<<endl;
}