• COCI. RIJEKA



    COCI.RIJEKA

    题目类型:虚拟题目 时间限制:1.0s 空间限制:64.0MB 提交文件大小限制:100.0KB 提示:%I64d & %I64u
     
    一条大河边上有M+1个村庄,村庄从0到M依次编号,,每个相邻村庄间的距离为1.MIRKO 住在0号村庄,他要驾船到M个村庄去,沿途有N个人要上船并到自己的目的地。MIRKO将送每一个人到他们的目的地,并最后将船停在M村庄。他的船足够大能装下所有的人,问他要航行的最短距离是多少?
    一个例子。A要从村庄2到村庄8,B要从村庄6到村庄4。MIRKO可以先从0到2让A上船,然后到6,让B上船,然后到4让B下,然后到8,最后到M。
    INPUT
    第一行两个整数 N and M (N ≤ 300 000, 3 ≤ M ≤ 10^9).
    接下来N行,每行两个整数,表示人们的要求.
    OUTPUT
    一个数,表示最短距离.
    SCORING
    In test cases worth a total of 40% points, N ≤ 5000 will hold.
    In test cases worth a total of 50% points, M ≤ 2000000 will hold.
    EXAMPLE TEST DATA
    input
    2 10
    2 8
    6 4
    output
    14
    input
    8 15
    1 12
    3 1
    3 9
    4 2
    7 13
    12 11
    14 11
    14 13
    output
    27
     
     
     

    Problem:
    题意还是比较清楚,求最小情况
     

    Solution:
    刚开始我们可以找找规律,看看特殊情况之类的
    首先我们必然会走的路:

    我们需要从0走到m

    那么如果一个任务是是正向的

    a->b a<=b的话,那么我们可以顺路得完成,不用多余的路

    1和2都被顺路完成

    而3是从0-m是最长的,我们就可以知道,如果任务是a->b a<=b的都可以被忽略,因为都可以被顺路完成

     

    那么我们现在就只用考虑a->b a>b 倒着走的

    逆向的情况根据刚刚我们正向分析的性质,也只到包含关系的内部可以省略

    5可以省略

    所以最后我们只用考虑的情况是

    考虑我们是把4完成了,再完成5,还是4,5一起完成?

    我们发现4,5一起完成会少走他们交集的那么段路

     

    并且我们发现多个情况,也是一起完成是会更优

    所以我们就有了贪心策略

    只有有交集的都一起完成,否则就单独完成


    附上代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=3e5+12;
    int n,m;
    struct node
    {
        int l,r;
        bool operator < (const node & other )const 
        {
            if(l==other.l) {return r<other.r;}
            return l< other.l;
        }
    }edge[N];
    int cnt;
    long long f[N];
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        scanf("%d%d",&n,&m);
        int a,b;
        for(int i=1;i<=n;i++) 
        {
            scanf("%d%d",&a,&b);
            if(a<=b) continue;
            edge[++cnt]=(node){b,a};
        }
        sort(edge+1,edge+cnt+1);
        int mx=0;int temp=cnt;cnt=0;
        for(int i=1;i<=temp;i++) 
        {
            if(edge[i].r<=mx) continue;
            edge[++cnt]=edge[i];
            mx=max(mx,edge[i].r);
        }
        
        f[1]=1LL*edge[1].l+(long long)(edge[1].r-edge[1].l)*3;
    
        int l=edge[1].l,r=edge[1].r;int id=1;
        for(int i=2;i<=cnt;i++) 
        {
            if(edge[i].l<=r) 
            {
                f[i]=f[id-1]+(long long)(edge[i].r-l)*3+1LL*(edge[id].l-edge[id-1].r);
                r=max(r,edge[i].r);
            }
            else 
            {
                f[i]=f[i-1]+(long long)(edge[i].r-edge[i].l)*3*1LL+1LL*(edge[i].l-edge[i-1].r);
                l=edge[i].l;r=edge[i].r;id=i;
            }
        }
        long long ans=f[cnt]+1LL*(m-edge[cnt].r);
        printf("%lld
    ",ans);
        return 0;
    }

     
     
     
     
     
  • 相关阅读:
    景深概念与计算
    机器视觉相关术语
    Inno Setup 怎么编译文件的版本号
    Qt 可执行程序写入版本信息
    Qt 程序默认管理员权限运行
    Inno Setup 改变默认路径
    Inno Setup 打包安装程序中让“是否创建快捷方式”默认为“打钩”的方法
    Inno Setup 如何让生成的setup.exe文件双击以管理员权限打开
    Inno Setup 打包出的安装程序以管理员身份运行
    InnoSetup 安装前卸载旧版程序
  • 原文地址:https://www.cnblogs.com/Heey/p/9125993.html
Copyright © 2020-2023  润新知