观光公交

 

题解:用一个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 } 

 

posted @ 2018-11-01 08:51  lcan  阅读(173)  评论(0编辑  收藏  举报