题解:用一个last数组表示从这个点出发的时间,用一个enter数组表示到达这个点的时间
每次使用一个加速器后,都应该更新一下enter,防止出现了新的车等人的界点,我的直接减去dis的做法就是没有考虑这一点,所以最终答案会少一些
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxn=10007; int n,m,k,ans,maxx; int dis[maxn],last[maxn],g[maxn],enter[maxn],sum[maxn]; struct Ren{ int t,a,b; }ren[maxn]; void work(){ while(k){ k--; g[n]=n; int tar;maxx=-1; for(int i=n-1;i>=2;i--){ if(enter[i]<=last[i]) g[i]=i; else g[i]=g[i+1]; } for(int i=2;i<=n;i++){ int tmp=sum[g[i]]-sum[i-1]; if(tmp>maxx&&dis[i]>0){ maxx=tmp;tar=i; } } ans-=maxx;dis[tar]--; for(int i=2;i<=n;i++) enter[i]=max(enter[i-1],last[i-1])+dis[i]; } } int main(){ cin>>n>>m>>k; for(int i=2;i<=n;i++) cin>>dis[i]; for(int i=1;i<=m;i++){ int t,a,b;cin>>t>>a>>b; ren[i]=(Ren){t,a,b}; } for(int i=1;i<=m;i++){ last[ren[i].a]=max(last[ren[i].a],ren[i].t); sum[ren[i].b]++; } enter[1]=last[1]; for(int i=1;i<=n;i++) sum[i]+=sum[i-1]; for(int i=2;i<=n;i++) enter[i]=max(enter[i-1],last[i-1])+dis[i]; for(int i=1;i<=m;i++) ans+=enter[ren[i].b]-ren[i].t; work(); cout<<ans<<endl; return 0; }
另外,这里的enter和last数组很巧妙的解决了问题,不像我的,这么复杂
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<vector> 7 #include<stack> 8 #include<map> 9 #include<set> 10 #include<queue> 11 using namespace std; 12 int read(){ 13 int x=0,f=1;char s=getchar(); 14 while(s<'0'||s>'9'){if(s=='-') f=-1;s=getchar();} 15 while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} 16 return f*x; 17 } 18 const int maxn=1007; 19 const int maxm=10007; 20 int n,m,k,ans,sheng; 21 int d[maxn],xia[maxn],val[maxn],shi[maxn],g[maxn],sum[maxn],last[maxn]; 22 bool deng[maxn]; 23 struct Ren{ 24 int t,a,b; 25 }ren[maxm]; 26 struct Lu{ 27 int dis,val,hao; 28 }lu[maxn]; 29 bool cmp(Ren a,Ren b){ 30 if(a.a==b.a) return a.t<b.t; 31 return a.a<b.a; 32 } 33 bool cmp2(Lu a,Lu b){ 34 if(a.val==b.val) return a.hao<b.hao; 35 return a.val>b.val; 36 } 37 void pre(){ 38 int r=0;int tim=0; 39 for(int i=1;i<=n;i++){ 40 while(ren[r+1].a==i) r++; 41 shi[i]=tim+d[i]; 42 if(ren[r].t>tim+d[i]){ 43 deng[i]=true;tim=ren[r].t; 44 } 45 else tim+=d[i]; 46 last[i]=tim; 47 } 48 for(int i=1;i<=m;i++) xia[ren[i].b]++; 49 for(int i=2;i<=n;i++){ 50 int wei=i,cnt=0; 51 while(!deng[wei]){cnt+=xia[wei];wei++;} 52 cnt+=xia[wei]; 53 lu[i]=(Lu){d[i],cnt,i}; 54 } 55 for(int i=1;i<=m;i++){ 56 ans+=shi[ren[i].b]-ren[i].t; 57 } 58 for(int i=1;i<=n;i++) sum[i]=sum[i-1]+xia[i]; 59 } 60 void work(){ 61 sort(lu+2,lu+n+1,cmp2); 62 for(int i=2;i<=n;i++){ 63 if(k>=lu[i].dis){ 64 k-=lu[i].dis;sheng+=lu[i].dis*lu[i].val; 65 } 66 else{ 67 lu[i].dis-=k;sheng+=k*lu[i].val; 68 break; 69 } 70 } 71 } 72 int main(){ 73 n=read();m=read();k=read(); 74 for(int i=2;i<=n;i++) d[i]=read(); 75 for(int i=1;i<=m;i++){ 76 int t,a,b;t=read();a=read();b=read(); 77 ren[i]=(Ren){t,a,b}; 78 } 79 sort(ren+1,ren+m+1,cmp); 80 pre(); 81 work(); 82 cout<<ans-sheng<<endl; 83 }