題解:貪心策略----使用一次加速器,只會對當前第i站車上的乘客以及已經到第i+1站的乘客做出貢獻,每次貪心尋找到最優的站台加速即可。
#include<iostream> #include<cstdlib> #include<cstdio> #include<cmath> #include<algorithm> #include<vector> #include<set> #include<cstring> #include<queue> #include<stack> #define MAXN 200010 #define LL long long int using namespace std; const int INF=1e9; const int EPS=1e-8; struct node{ int T; int A; int B; }a[MAXN]; int n,m,k; int ans; int d[MAXN];//從i到i+1的時間 int t[MAXN];//到達i的時刻 int f[MAXN];//最晚到達i的乘客的時刻 int g[MAXN];//在i車站加速最大影響到的車站 int sum[MAXN];//前i個車站下車的人數 int main() { freopen("1.in","r",stdin); // freopen("1.out","w",stdout); scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=n-1;i++) scanf("%d",&d[i]); for(int i=1;i<=m;i++) { scanf("%d%d%d",&a[i].T,&a[i].A,&a[i].B); f[a[i].A]=max(f[a[i].A],a[i].T);//求出最晚到的乘客時刻 sum[a[i].B]++; } for(int i=2;i<=n;i++) sum[i]+=sum[i-1];//前綴和求人數 t[1]=0; for(int i=2;i<=n;i++) t[i]=max(t[i-1],f[i-1])+d[i-1];//當前到達i的時刻 for(int i=1;i<=m;i++) ans+=t[a[i].B]-a[i].T;//旅游時間 while(k>0) { g[n]=n; g[n-1]=n; for(int i=n-2;i;i--) { if(t[i+1]<=f[i+1])//如果下一站的需要等待的乘客到達時間大於到達的時刻,那么在i+1車站之后站下車的乘客不會收到在i加速的影響 g[i]=i+1; else g[i]=g[i+1]; } int maxl=0,j; for(int i=1;i<=n;i++) if(sum[g[i]]-sum[i]>maxl&&d[i]>0)//找到影響最多人的車站,貪心策略 maxl=sum[g[i]]-sum[i],j=i; if(!maxl) break; ans-=maxl; d[j]--;//加速 k--;//少了一個 t[1]=0; for(int i=2;i<=n;i++) t[i]=max(t[i-1],f[i-1])+d[i-1];//再次貪心 } cout<<ans<<endl; return 0; }