zoukankan      html  css  js  c++  java
  • YYHSOI模拟赛题解(T1装果子)

    题目描述

    果园里有n颗果树,每棵果树都有一个编号i(1≤in)。小明已经把每棵果树上的果子都摘下来堆在了这棵树的下方,每棵树下方的果子体积为ai

    现在小明将拿来m个袋子把这些果子都装进袋子里。每个袋子的体积为v。小明会按照如下规则把果子装进袋子里:

    (a)从第1棵果树开始装起,由1到n一直装到第n棵果树。

    (b)如果这棵果树下的果子能全部装进当前这个袋子,就装进去;如果不能,就关上当前这个袋子,打开一个新的袋子开始装。

    小明希望在能把所有果子都装进袋子里的前提下,v尽量小。m个袋子并不一定都要装进果子。

    输入

    输入文件名为fruit.in

    输入第1行,包含两个整数nm

    第2行,包含n个整数ai

    输出

    输出文件名为fruit.out

    输出仅1行,表示最小的v

    样例输入

    fruit.in 3 3 1 2 3 fruit.out 3 fruit.in 5 3 1 3 6 1 7 fruit.out 7 fruit.in 6 3 1 2 1 3 1 4 fruit.out 4

    样例输出

    【输入输出样例解释1】 每个袋子的体积为3即可。前2棵果树的果子装在第一个袋子里,第3棵果树的果子装在第二个袋子里。第三个袋子不用装了。 【输入输出样例解释2】 每个袋子的体积为7即可。前2棵果树的果子装在第一个袋子里,此时第一个袋子已经装了4单位体积的果子,第3棵果树的果子装不下了,所以装进第二个袋子里,第4棵果树的果子刚好装进第二个袋子,第5棵果树的果子装进第三个袋子里。 【输入输出样例解释3】 每个袋子的体积为4即可。前3棵果树的果子装在第一个袋子里,第4~5棵果树的果子装在第二个袋子里,第6棵果树的果子装在第三个袋子里。

    提示

    【数据范围】


    对于40%的数据,0<mn≤1,000,0<ai≤1,000;


    对于70%的数据,0<mn≤100,000,0<ai≤100,000;


    对于100%的数据,0<mn≤100,000,0<ai≤1,000,000,000。

     

    这一道题目我们会发现一个性质,就是说如果对于一个V它是可行的,那么V+1一定可行,但是V-1可能可行,又因为题目中需要的是尽可能小的V,所以如果对于一个V是可行的,我们只要检查小于等于V中的数是否合法。同理如果对于一个V是不可行的,那么V+1可能可行,V-1一定不可行。所以如果一个V是不可行的,我们只要检查查找比它大的V就行了。而检验一个V是否可行,我们可以线扫一遍可以得出对于V而言,它所需要的袋子数量。而寻找V,我们用到的就是二分答案(由前面的性质可得)。所以时间复杂度O(N*log(MaxSum))合情合理。

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 
     7 using namespace std;
     8 
     9 int N,M;
    10 long long a[1000005];
    11 
    12 bool check(long long X)
    13 {
    14     long long tmp=0;
    15     int num1=1;
    16     for (int i=1; i<=N; i++)
    17     {
    18         tmp+=a[i];
    19         if (tmp > X)
    20         {
    21             tmp=a[i];
    22             num1++;
    23         }
    24         if (X < a[i])
    25         {
    26             return false;
    27         }
    28     }
    29     if (num1 <= M) return true;
    30     else return false;
    31 }
    32 
    33 int main()
    34 {
    35     scanf("%d%d",&N,&M);
    36     long long r=-1;
    37     for (int i=1; i<=N; i++)
    38     {
    39         scanf("%lld",&a[i]);
    40         r=max(r,a[i]);
    41     }
    42     long long l=r; r=r * N;
    43     while (l < r)
    44     {
    45         long long mid=(l + r) / 2;
    46         if (check(mid)) r=mid;
    47         else l=mid+1;
    48     }
    49     printf("%lld\n",l);
    50     return 0;
    51 }
    Show My Ugly Code
     
  • 相关阅读:
    LENGTH()和CHAR_LENGTH()区别
    使用ibatis时 sql中 in 的参数赋值(转)
    数据库类型空间效率探索(五)- decimal/float/double/varchar
    MySQL用命令行复制表的方法
    升讯威微信营销系统开发实践:微信接口的 .NET 封装
    Github开源:Sheng.RabbitMQ.CommandExecuter (RabbitMQ 的命令模式实现)
    开源 & 免费使用 & 打包下载自行部署 :升讯威 周报系统
    开源 & 免费使用 & 打包下载自行部署 :升讯威 周报系统
    GitHub开源:升讯威ADO.NET增强组件 sheng.ADO.NET.Plus V1.3
    [源代码] SailingEase .NET Resources Tool (.NET 多语言资源编辑器)
  • 原文地址:https://www.cnblogs.com/TUncleWangT/p/7055116.html
Copyright © 2011-2022 走看看