- \(t[i]\),最晚到达 \(i\) 站的人到达的时间;
- \(arrive[i]\),车到达 \(i\) 站的时间,显然 \(arrive[i]=max(arrive[i-1],t[i-1])+D[i-1]\)。
所以要求的答案就是:\(\sum arrive[target[i]]-reach[i]\),\(reach[i]\)为\(i\)到站的时间
当我们考虑到加速器的时候,对于一个站,当 \(arrive[i]<=t[i]\) 时,前面不管用了多少个加速器都不会影响到后面的时间,所以我们再设这样一个东西:\(f[i]\)为,在 \(i\) 这个站用了加速器后能够影响到的 \(i\) 后面最远的站,当 \(arrive[i]<=t[i]\) 时,\(f[i]=i+1\),否则,\(f[i]=f[i+1]\)。所以我们在 \(i\) 站用一个加速器,就会使得答案减少 \(S[f[i]]-S[i]\) ,其中,\(S[i]\)为在 \(i\) 站下车的人数的前缀和,所以我们只需要每次在一个使得 \(S[f[i]]-S[i]\) 最大的 \(i\) 上放一个加速器并实时更新一下 \(arrive[i]\) 和 \(f[i]\) 就好了//made by Hero_of_Someone#include#include #include #define N (1010)#define RG registerusing namespace std;inline int gi(){ RG int x=0,q=1; RG char ch=getchar(); while( ( ch<'0' || ch>'9' ) && ch!='-' ) ch=getchar(); if( ch=='-' ) q=-1,ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x; }int n,m,k,D[N],ret;int t[N],arrive[N],S[N],f[N];void init(){ n=gi(),m=gi(),k=gi(); for(RG int i=1;i Max&&D[i]) Max=S[f[i]]-S[i],s=i; if(!Max) break; D[s]--; k--; for(RG int i=1;i<=n;i++) arrive[i]=max(arrive[i-1],t[i-1])+D[i-1]; } for(RG int i=1;i<=n;i++) ret+=arrive[i]*(S[i]-S[i-1]); printf("%d\n",ret);}int main(){ init(); work(); return 0; }