• P1315 观光公交


    P1315 观光公交

    题解

    贪心大法好啊

    思路:
    先计算出不加速的时候的时间
    然后考虑在哪里加速
    用一开始的时间不断减就好啦

    先考虑不加速:
    由于人到达车站的时间是不会改变的
    所以每个车站的出发时间是不会改变的
    就是:start[ i ] = max(last[ i ] , arrive[ i ])
              arrive[ i+1 ] = start[ i-1 ] + d[ i ]

    所以最后累加每个人的QWQ得到最初答案


    然后考虑往哪里加??
    (1)如果你到达这个站点 i 的时候,最后一名乘客还没来
             也就是车等人,就没有必要加速了,因为对后面的站点无影响,而且加了也没大有用
    (2)如果是人等车,还是可以考虑考虑的
             可能会对后面的站点造成影响

    车每到达一个站点,就会有一部分人上车,一部分人下车
    (不排除没人上下车的可能吧,不知道数据)
    然后这些人就会产生等待时间和乘车时间,对答案产生影响
    所以我们就找到站点中影响人数最多的那个,对ta加速就好了

                           sum[ i ] 前缀和维护到达站点i及之前站点的总人数
    yx[ i ] (yingxiang影响)记录站点i可以影响到的最大站点编号

    so,sum[ yx[ i ] ] - sum[ i ] 就是可以影响到的最多人数


    这样人数多的就要放加速器
    贪心就是这里


    接下来枚举,一个一个找要放加速器的位置

    每次使用加速器后站点的影响可能会发生改变,因此每次重算

    然后寻找影响最大的站点,缩短路程,ans更新
    然后更新arrive&start

    最后输出答案

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    inline int read()
    {
        int ans=0;
        char last=' ',ch=getchar();
        while(ch<'0'||ch>'9') last=ch,ch=getchar();
        while(ch>='0'&&ch<='9') ans=ans*10+ch-'0',ch=getchar();
        if(last=='-') ans=-ans;
        return ans;
    }
    
    const int maxn=1010,maxm=10010;
    int n,m,k;
    int d[maxn],arrive[maxn],start[maxn],last[maxn],yx[maxn],sum[maxn];
    int ans,maxx=-1;
    struct node
    {
        int u,v,w;
    }peo[maxm];
    
    void chuli(int x)
    {
        while(x)
        {
            --x;
            int goal;  //要加速的站点编号 
            maxx=-1;   //最大影响人数 
            yx[n-1]=yx[n]=n;
            for(int i=n-2;i>=1;i--)
            {
                if(arrive[i+1]<=last[i+1]) yx[i]=i+1;  //车等人,最多对后一个点产生影响 
                else  yx[i]=yx[i+1];  //人等车 
            }
    
            for(int i=1;i<n;i++)  //枚举可能使用加速器的站点(肯定不用考虑 
            {
                int kk=sum[yx[i]]-sum[i];
                if(kk>maxx&&d[i]>0)
                {
                    maxx=kk;
                    goal=i;
                }
            }
            
            ans-=maxx;  //人数即加速的时间 
            d[goal]--;
        
            for(int i=1;i<=n;i++)  //更新arrive&start 
            {
                start[i]=max(last[i],arrive[i]);
                arrive[i+1]=start[i]+d[i];
            }
        
        }
        return ;
    }
    
    int main()
    {    
        n=read();m=read();k=read();
        
        for(int i=1;i<n;i++)
          d[i]=read();
          
        for(int i=1;i<=m;i++)
        {
            peo[i].w =read();
            peo[i].u =read();
            peo[i].v =read();
            sum[peo[i].v]++;   //到站人数 
            last[peo[i].u]=max(last[peo[i].u],peo[i].w );
        }
        
        arrive[1]=0;
        for(int i=1;i<=n;i++)
        {
            sum[i]+=sum[i-1];
            start[i]=max(last[i],arrive[i]);
            arrive[i+1]=start[i]+d[i];
        }
    
        for(int i=1;i<=m;i++)
        {
            ans+=(arrive[peo[i].v]-peo[i].w);
        }
    
        chuli(k);
        
        printf("%d
    ",ans);
        
        return 0;
    }
  • 相关阅读:
    Python--day62--什么时候用GET请求和POST请求
    Python--day62--ORM的使用
    使用 vs code 搭建vue项目(一)
    jquery如何模拟分页-小白进阶
    JavaScript 实现的4种数字千位符格式化方法
    web秀
    五十个UI设计资源网站
    基于 HTML5 WebGL 的 水泥工厂可视化系统
    ASP.NET MVC图片管理(上传,预览与显示)
    jQuery使用FormData上传文件
  • 原文地址:https://www.cnblogs.com/xiaoyezi-wink/p/11162234.html
Copyright © 2020-2023  润新知