题意:2011noip原题,不再赘述。
之前贪心的做法固然是正确的。但一个一个加速器用显得太慢了,能不能一次性使用多个加速器呢?
答案完全是可以的,同之前贪心策略类似的,关注每站的T_up_max和T_down_max,以及每站的下车人数,并将其前缀和维护。 那么就找max(T_down_max-T_up_max),即使用加速器的个数。
#include<bits/stdc++.h>
#define REP(i,f,t) for(int i=(f),i##_end_=(t);i<=i##_end_;i++)
#define DREP(i,f,t) for(int i=(f),i##_end_=(t);i>=i##_end_;i--)
#define LL long long
#define INF 0x3f3f3f3f
#define N 1005
#define M 10005
#define S 100005
using namespace std;
int n,m,k;
int ans;
int dis[N];
int down[M],up[M];
int sum[N],g[N];
struct node{
int t,s,e;
}A[M];
struct Node{
int L,R;
bool operator<(const Node &a)const{
return sum[R]-sum[L]<sum[a.R]-sum[a.L];
}
};
priority_queue<Node>Q;
void Init(){
REP(i,1,m)sum[A[i].e]++,up[A[i].s]=max(up[A[i].s],A[i].t);
REP(i,1,n)down[i]=max(down[i-1],up[i-1])+dis[i-1];
REP(i,1,n)sum[i]+=sum[i-1];
REP(i,1,m)ans+=down[A[i].e]-A[i].t;
}
void solve(){
Q.push((Node){1,n});
while(!Q.empty()&&k){
int l=Q.top().L,r=Q.top().R;
Q.pop();
int Mx=min(k,dis[l]),pos=-1;
REP(i,l+1,r-1)if(down[i]-up[i]<Mx)Mx=down[i]-up[i],pos=i;
if(Mx>0){
k-=Mx;
ans-=(sum[r]-sum[l])*Mx;
dis[l]-=Mx;
REP(i,1,n)down[i]=max(down[i-1],up[i-1])+dis[i-1];
}
if(pos!=-1){
if(l<pos)Q.push((Node){l,pos});
if(pos<r)Q.push((Node){pos,r});
}
else if(l+1<r)Q.push((Node){l+1,r});
}
}
int main(){
scanf("%d%d%d",&n,&m,&k);
REP(i,1,n-1)scanf("%d",&dis[i]);
REP(i,1,m)scanf("%d%d%d",&A[i].t,&A[i].s,&A[i].e);
Init();
solve();
printf("%d\n",ans);
return 0;
}