P1315 观光公交 - 贪心

Posted dprswdr

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1315 观光公交 - 贪心相关的知识,希望对你有一定的参考价值。

传送门

k=0时,直接模拟...

k=1时,找指向下车乘客最多的站的边,使用加速器。

k>1时,我们枚举每个加速器,类似上一问的做法,暴力找一遍影响最大的边,然后更新答案。

令g[i]表示边i所能影响到的最远的站。

当 到达站i+1的时间>=站i+1晚到达的人的到达时间时,即到达站i+1时可以直接前往站i+2,则在边i使用加速器是有意义的。

则边i能影响到的站为边i+1能影响到的最远的站。

反之,当到达站i+1时仍需等待最晚的人上车,说明在边i使用加速器与不使用没什么区别。

此时,则边i能影响到的站就是站i+1。

最后我们枚举每一条边,看在站i~g[i]下车人数最多的边i是那一条,就在这一条边使用加速器。

我们可以用前缀和sum[g[i]]-sum[i]来加速判断。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1000+100,M=10000+100;
int d[N];//连接站i与站i+1的边i的边权 
int sum[N];//站1~i下车人数之和 
int lst[N];//站i最后一个到达的人的到达时间
int ari[N];//站i的到达时间
int g[N];//在边i使用加速器所能够影响到的最远的站g[i] 
int tim[M],fro[M],to[M];//乘客i到达时间 乘客i从站fro[i]出发 去往站to[i] 
//数组别开小了!!! 
int main(){
    int n,m,k;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<n;i++){
        scanf("%d",&d[i]);
    } 
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&tim[i],&fro[i],&to[i]);
        sum[to[i]]++; 
        lst[fro[i]]=max(lst[fro[i]],tim[i]);
    }
    for(int i=1;i<=n;i++) sum[i]+=sum[i-1];
    ari[1]=0;
    for(int i=2;i<=n;i++){
        ari[i]=max(ari[i-1],lst[i-1])+d[i-1];
        //计算到达每个站的时间 
    }
    int ans=0;
    for(int i=1;i<=m;i++){
        ans+=ari[to[i]]-tim[i];
        //计算不使用加速器时最初的答案 
    }
    //O(nk) 暴力使用每个加速器 
    while(k--){
        g[n-1]=n;//在边n-1使用加速器所能够影响的最远的站为站n 
        for(int i=n-2;i;i--){
            if(ari[i+1]>lst[i+1]) g[i]=g[i+1];
            //如果刚到站i+1即可前往下一个站;
            //说明在边i使用加速器所能影响到的最远的点相当于在边i+1使用加速器所能影响到的最远的点
            else g[i]=i+1;
            //若到达站i+1后仍需等待乘客上车,说明在边i使用加速器无意义。 
        }
        //暴力找影响最大的边
        int res=-1,pos=0;
        for(int i=1;i<n;i++){
            if(d[i]&&sum[g[i]]-sum[i]>res){
                res=sum[g[i]]-sum[i];
                pos=i;
            }
        }
        if(res==-1) break;
        //说明无法再使用加速器 
        d[pos]--;
        ans-=res;
        //使用一个加速器,每一个车上乘客的到达时间减1,即答案减去车上乘客的数量 
        for(int i=2;i<=n;i++){
            ari[i]=max(ari[i-1],lst[i-1])+d[i-1];
            //重新计算使用加速器后到达每个站的时间 
        }
    }
    printf("%d",ans);
    return 0;
}

 

以上是关于P1315 观光公交 - 贪心的主要内容,如果未能解决你的问题,请参考以下文章

P1315 观光公交 - 贪心

LUOGU P1315 观光公交(贪心)

洛谷P1315 观光公交

P1315 观光公交

[NOIP2011] 提高组 洛谷P1315 观光公交

Luogu P1315 观光公交