SOL
挺不錯的一道貪心題,小學奧數的較多
最開始分析樣例,很多人可能會考慮直接讓所有氮氣加速器用在下車人數最多的那個車站的前面那條路上,不過發現有車等人、人等車的問題之後,你可能就會覺得這道題不是一個貪心題了
事實上,這還是一道貪心題,只不過次氮氣加速要一次一次的使用,這個思路應該能夠在嘗試推導的做法之後想到,用一次氮氣加速時,我們考慮人等車的區間貢獻最大的一段,並且保證用了之後不會變成車等人,也就是目前車到達站點的時間大於最晚到此站的人的時間,求出這麼一段區間,然後對最前面那一段使用一次氮氣加速,那麼整個區間的時間都會減少,求出下車人數最多的一段即可
用了一次之後,可能會出現有些地方從人等車變成車等人,因此要從頭考慮,做完次統計答案即可
複雜度
代碼:
#include<bits/stdc++.h>
#define re register
using namespace std;
inline int rd(){
int data=0;static char ch=0;ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))data=(data<<1)+(data<<3)+(ch^48),ch=getchar();
return data;
}
const int M=1e4+5,N=1005;
int n,m,k,st[M],ed[M],ans,dis[N],off[N],last[N],beg[N],tim,mx,now,pos;
signed main(){
n=rd(),m=rd(),k=rd();
for(int re i=1;i^n;++i)dis[i]=rd();
for(int re v,i=1;i<=m;++i)st[i]=rd(),v=rd(),ed[i]=rd(),last[v]=max(last[v],st[i]),++off[ed[i]];
for(int re i=1;i<=n;++i)beg[i]=tim,tim=max(tim,last[i]),tim+=dis[i];
while(k--){
mx=0;
for(int re i=2;i<=n;++i){
if(!dis[i-1])continue;
now=0;
for(int re j=i;j<=n;++j){
now+=off[j];
if(beg[j]<=last[j])break;
}if(now>mx)mx=now,pos=i;
}--dis[pos-1];
for(int re i=pos;i<=n;++i){
--beg[i];
if(beg[i]<last[i])break;
}
}
for(int re i=1;i<=m;++i)ans+=beg[ed[i]]-st[i];
printf("%d",ans),exit(0);
}