zoukankan      html  css  js  c++  java
  • Codeforces Round #515 (Div. 3) D. Boxes Packing

      

    比赛的时候这题的题意一直没看懂,后面才明白意思就是有n个物品,然后要求最多可以挑选出多少物品,挑选过程是从第一给物品开始往右边挑选,对于每一个物品,如果目前的盒子剩余空间是>=该物品的体积的就直接放进盒子,继续挑选下一个物品,若目前的盒子剩余空间是<该物品的体积的,那就要另外开一个盒子来放物品了,若目前已经没有可用的盒子了,说明这次选取是非法的,那么之前选取的所有物品都不可以得到,然后就把选取的第一个物品退回去,看是否有剩余的空间放下该物品,如果还是放不下的话,继续把第二个拿的物品退回去,直至可以放下该物品为止,然后继续选取下去,若目前还有可用的盒子,那就继续选取下去。选取物品的终点是把最后一个物品也选取了,这样的选取才是合法的,那么盒子的选取的物品的数量的最大值即是我们要的,这个过程可以看出是依次从第1个至第n个物品开始选取物品,若可以把最后一个也选了,那就更新答案,但是这样的话复杂度2e5*2e5是会超时的,然后可以发现起点越大挑选成功的可能性越大,具有单调性,因此可以用二分。

    #include<bits/stdc++.h>
    using namespace std;
    #define fuck(x) cout<<#x<<" "<<x<<endl;
    const int maxn=2e5+10;
    int n,m,k,a[maxn];
    bool check(int mid)
    {
        int rp=k,num=1;
        for(int i=mid;i<=n;i++)
        {
            if(rp>=a[i])
            {
                rp-=a[i];
            }
            else
                if(num<m)
                {
                    num++;
                    rp=k-a[i];
                }
                else
                    return false;
        }
        return true;
    }
    int main()
    {
        scanf("%d %d %d",&n,&m,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&(a[i]));
        }
        int low=1,high=n,mid,ans=0;
        while(low<=high)
        {
            mid=(low+high)/2;
            if(check(mid))
            {
                ans=max(ans,n-mid+1);
                high=mid-1;
                //fuck(mid);
            }
            else
                low=mid+1;
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Cookie
    webSocket+HeadBeat
    Javascript-多个数组是否有一样值
    后缀补全用得好,提前下班没烦恼
    Nginx 究竟如何处理事件?
    9 个习惯助你在新的一年更有精力
    一篇文章带你了解 ZooKeeper 架构
    浅析 Nginx 网络事件
    ZooKeeper 入门看这篇就够了
    如何优雅地关闭worker进程?
  • 原文地址:https://www.cnblogs.com/eason9906/p/11754862.html
Copyright © 2011-2022 走看看