zoukankan      html  css  js  c++  java
  • IOI2015 boxes纪念品盒

    BZOJ 4368: [IOI2015]boxes纪念品盒

    BZOJ传送门

    Description

    IOI2015开幕式正在进行最后一个环节。按计划在开幕式期间,每个代表队都将收到由主办方发放的一个装有纪念品的盒子。然而所有志愿者都被精彩的开幕式所吸引,除Aman外其他人完全忘记了发放纪念品这件事。Aman是一位热情的志愿者,为使得IOI尽量圆满,他要用最短的时间将所有纪念品发放出去。

    开幕式的场地是一个圆环,被分为 个完全相等的区域,这些区域的编号依次为 到,也就是说,对于0≤i≤L-2,区域i与区域i+1相邻,且区域L-1与区域0相邻。场地上共有N个代表队,每队坐在上面的一个区域上,每个区域可以包含任意多个代表队,也可以为空。

    共有N个相同的纪念品。开始,Aman和所有纪念品都在区域0。Aman应该给每队一个纪念品,并且在发放完最后一个纪念品后他必须回到区域0。注意,有些队可能坐在区域0。

    在任意时刻,Aman只能够携带至多K个纪念品。Aman必须从区域0取走这些纪念品,且取纪念品不需要时间。纪念品一旦从区域0被取走后,Aman只能将其发放给某个代表队或者随身携带。无论何时,Aman携带一个或更多的纪念品到达一个这样的区域,该区域有一个代表队尚未收到纪念品,Aman便可将他携带的一个纪念品发给这个代表队。这种发放也在瞬间完成。他所花的时间都消耗在区域之间的移动上。无论携带多少纪念品,Aman都需要1秒钟从一个区域移动到其相邻的区域(可以顺时针移动也可以逆时针移动)。

    你的任务是计算出Aman发放完所有纪念品并返回到他的最初区域所需要的最短时间(秒数)。

    Input

    第一行: N K L

    第二行: positions[0] … positions[N-1]

    N: 代表队的数目。

    K: Aman在同一时间能够携带纪念品的最大数目。

    L: 开幕式场地上的区域数目。

    positions: 一个长度为N的数组,positions[0],...,positions[N-1]给出了所有代表队所在区域的编号。positions 的元素按非递减排序。

    Output

    一个整数,表示Aman 能够完成这一任务所需的最短时间(秒数)。

    Sample Input

    3 2 8
    1 2 5

    Sample Output

    10

    HINT

    img

    题解:

    2019.10.31 IOI模拟赛T1(滑稽)爆零场

    一开始想到的是贪心,但是贪心策略一直是错的,思路也不是很清晰,通过特判拿了25分但是数据强一点还是爆零。

    还是感谢一下出题人吧@EM-LGH

    正解思路:

    很容易发现这样一个走路方式:

    对于这个圈,我们可以向左走几个点,原路返回。也可以向右走几个点然后返回。这是我在考场上想到的。但我忽略了一种情况:也可以走一圈回来(就是向左/向右走几个点之后不原路返回直接从另一个方向回去)。

    那么剩下的是我们的决策过程。我们发现,走一圈这种决策只能使用一次,因为走两圈一共会分发(2k)个纪念品,根据抽屉原理,左边和右边肯定会有一侧(ge k),那么就不是最优决策。

    那么,贪心一下,先用原路返回的方式处理一下比较优的抉择,也就是离零点比较近的左右点。然后再走一圈完事。

    代码:

    #include<cstdio>
    #include<algorithm>
    #define int long long
    using namespace std;
    const int maxn=1e7+10;
    int n,k,l;
    int sl[maxn],sr[maxn],cntl,cntr;
    int fl[maxn],fr[maxn];
    signed main()
    {
        scanf("%lld%lld%lld",&n,&k,&l);
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%lld",&x);
            if(x<=l/2)
                sl[++cntl]=x;
            else
                sr[++cntr]=l-x;
        }
        for(int i=1;i<=cntr && i<=cntr-i+1;i++)
            swap(sr[i],sr[cntr-i+1]);
        for(int i=1;i<=cntl;i++)
        {
            if(i<=k)
                fl[i]=sl[i];
            else
                fl[i]=fl[i-k]+sl[i];
        }
        for(int i=1;i<=cntr;i++)
        {
            if(i<=k)
                fr[i]=sr[i];
            else
                fr[i]=fr[i-k]+sr[i];
        }
        int ans=(fl[cntl]+fr[cntr])<<1;
        for(int i=cntl-k;i<=cntl;i++)
            ans=min(ans,(fl[i]+fr[max(cntr-k+cntl-i,0ll)])*2+l);
        printf("%lld",ans);
        return 0;
    }
    
  • 相关阅读:
    48、Windows驱动程序模型笔记(六),同步
    44、Windows驱动程序模型笔记(二)
    JavaP:对象创建
    JavaP:继承和多态【只有提纲】
    ASP.NET MVC:一个简单MVC示例
    JavaP: 2、类和对象
    ASP.NET MVC:解析 MVC+ADO.NET Entity(实体类)
    Oracle: 一、Oracle简介,安装,基本使用,建表增删改查,数据类型及常用命令
    JavaP:面向对象编程
    ASP.NET: PagedDataSource
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11771379.html
Copyright © 2011-2022 走看看