zoukankan      html  css  js  c++  java
  • CF1066D Boxes Packing(二分答案)

    题意描述:
    你有$n$个物品,每个物品大小为$a_i$,$m$个盒子,每个盒子的容积为$k$。$Maksim$先生想把物品装入盒子中。对于每个物品,如果能被放入当前的盒子中,则放入当前盒子,否则换一个新的盒子放入。为了放入尽可能多数量的物品,$Maksim$先生会从左开始扔掉一部分物品。现在,$Maksim$先生想知道,他最多能放入盒子多少物品
    输入输出格式:
    输入格式:
    第一行,三个整数$n$,$m$,$k$,$(1≤n,m≤2 	imes 10^5$,$ 1≤k≤10^9)$含义参见上文
    第二行,$n$ 个数,第$i$表示$a_i$
    输出格式:
    一行,一个数,表示$Maksim$先生能放入盒子里的最多的物品数量

    思路:

    水题。。。

    因为他挑选的规则一定,而删除的方式一定,所以,答案拥有单调性。

    单调性:因为有一个最大合法点,在那之后都是合法的,所以再往后走的话,答案一定越来越小

    所以我们的目的就是找这个最大合法点。

    怎么找呢?

    因为挑选方式一定,所以合法性可以O(n)验证。

    这样的话,很显然就可以用一个东西叫二分答案

    二分合法点就好了qwq

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define rii register int i
    #define rij register int j
    using namespace std;
    int n,m,k;
    int a[200005];
    bool check(int wz)
    {
        int now=0,cnt=1;
        for(rii=wz;i<=n;i++)
        {
            if(a[i]>k)
            {
                return false;
            }
            if(now+a[i]>k)
            {
                now=0;
                cnt++;
            }
            now+=a[i];
        }
        if(cnt>m)
        {
            return false;
        }
        return true;
    }
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(rii=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int l=1,r=n;
        while(l<r)
        {
            if(r-l==1)
            {
                if(check(l)==true)
                {
                    break;
                }
                else
                {
                    if(check(r)==true)
                    {
                        l=r;
                    }
                    else
                    {
                        l=n+1;
                    }
                    break;
                }
            }
            int mid=(l+r)/2;
            if(check(mid)==true)
            {
                r=mid;
            }
            else
            {
                l=mid;
            }
        }
        printf("%d",n-l+1);
    }
  • 相关阅读:
    linux centos 7.5 开启 postgresql 远程访问
    linux centos 7 开启 ftp
    CentOS 7.5 改IP后不生效无法上网解决办法
    Windows Server 2008R2 及上系统安装 Windows 可选功能
    C#只允许运行一个实例
    C# 命令行参数分割
    C# 获取所有已登录系统的用户名
    C#获取进程用户名
    psexec 用法
    检测 Visual C++ Redistributable Package 相应版本是否已安装
  • 原文地址:https://www.cnblogs.com/ztz11/p/9807557.html
Copyright © 2011-2022 走看看