洛谷P1315 观光公交

添加注释小能手上线。

贪心注意:

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 }

 

上一篇:ROS学习笔记(9)——在RVIZ上打造人机界面


下一篇:017 Linux 之啥是 ssh ?