添加注释小能手上线。
贪心注意:
1.本站使用加速器可能对后续站产生影响
2.若本站车等人,使用加速器也可使这一站下车的人提前下车,优化结果
3.若有剩余加速器,则一律用在n-1到n站之间
故正解应为:每次在当前情况下找出加速器使用的最优位置(途径人数最多),及时更新相关记录数组。
1 #include<bits/stdc++.h> 2 #define ff(s,e) for(int i=s;i<=e;i++) 3 using namespace std; 4 inline int read(){ 5 int x=0,f=1;char ch=getchar(); 6 while(ch>'9'||ch<'0'){ 7 if(ch=='-') f=-1; 8 ch=getchar(); 9 } 10 while(ch>='0'&&ch<='9'){ 11 x=(x<<1)+(x<<3)+(ch^48); 12 ch=getchar(); 13 } 14 return x*f; 15 } 16 const int N=100000; 17 int n,m,k; 18 int dis[N],last[N],g[N],enter[N],sum[N]; 19 //i->i+1时间 乘客i站到齐时间 i站时间影响到g[i]站 i站到达时间 i站影响人数; 20 int ans,maxx; 21 struct qwq{ 22 int t,st,ed; 23 }a[N]; 24 int main(){ 25 n=read();m=read();k=read(); 26 ff(1,n-1) dis[i]=read(); 27 ff(1,m){ 28 a[i].t=read();a[i].st=read();a[i].ed=read(); 29 last[a[i].st]=max(last[a[i].st],a[i].t); 30 sum[a[i].ed]++; 31 } 32 enter[1]=last[1]; 33 ff(1,n){ 34 sum[i]+=sum[i-1];//前缀和 35 } 36 ff(2,n){ 37 enter[i]=max(enter[i-1],last[i-1])+dis[i-1];//到站时间 38 } 39 ff(1,m){ 40 ans+=enter[a[i].ed]-a[i].t;//加速前答案 41 } 42 for(;k>0;k--){ 43 g[n]=g[n-1]=n; 44 int tar; 45 maxx=0; 46 for(int i=n-2;i>=1;i--){ 47 if(enter[i+1]<=last[i+1]) g[i]=i+1;//车等人 48 else g[i]=g[i+1];//人等车 49 } 50 ff(1,n-1){ 51 int tmp=sum[g[i]]-sum[i];//真.第i站影响人数 52 //若车等人,则使用加速器只使第i+1站下车的人(sum[i+1]-sum[i])提前下车 53 //若人等车,对后面各站均产生影响直到车等人或到最后一站 54 if(tmp>maxx&&dis[i]>0) maxx=tmp,tar=i; 55 } 56 ans-=maxx; 57 dis[tar]--; 58 ff(2,n){ 59 enter[i]=max(enter[i-1],last[i-1])+dis[i-1];//维护enter 60 } 61 } 62 printf("%d",ans); 63 return 0; 64 }