zoukankan      html  css  js  c++  java
  • 巧克力 二分

    [Description]

    现在有一块1*1*N 的巧克力(每个1*1*1 的部分有一个营养值Ai),想分给K 个小朋友,并且每个小朋友必须得到一整块,即最终只能分成K 块,每个小朋友所得到的营养值即为得到巧克力每部分的营养值之和。

    这几个小朋友的自尊心很强,尤其是不允许分得营养值最大的那个人所得的营养值太大。所以,为了照顾好他们,你必须使分得营养值最大的那个人的营养值尽量小。

    [Input]

    1 行:两个整数N K

    2 行:N 个整数Ai,相邻整数用空格隔开

    [Output]

    一行,分得最多的那个人的最少巧克力

    [Sample 1]

    chocolate.in

    chocolate.out

    5 2

    2 1 3 4 5

    9

    样例解释:有如下分法

    2 | 1 3 4 5 -> 2 13 -> max=13

    2 1 | 3 4 5 -> 3 12 -> max=12

    2 1 3 | 4 5 -> 6 9 -> max=9

    2 1 3 4 | 5 -> 10 5 -> max=10

    再对所有取小min=9

    [Hit]

    对于30%数据 N <= 30, K <= 10

    对于100%数据 N <= 100000, K <= N, Ai <= 10^9

     


    第一眼看到这题,我是懵逼,后来知道这题使用二分,再结合它只能整块分的性质,我们就可以写出怎么检查的过程,然后这题就没了。

    代码:

     

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    #define il inline
    #define db double
    using namespace std;
    il int gi()
    {
        int x=0,y=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
        if(ch=='-')
            y=-1;
        ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
        x=x*10+ch-'0';
        ch=getchar();
        }
        return x*y;
    }
    il ll gl()
    {
        ll x=0,y=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
        if(ch=='-')
            y=-1;
        ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
        x=x*10+ch-'0';
        ch=getchar();
        }
        return x*y;
    }
    int n,k;
    ll cho[100045];
    il bool check(ll x)
    {
        int sum=0;
        ll now=0;
        for(int i=1;i<=n;i++)
        {
        now+=cho[i];
        if(now>x)
        {
            sum++;
            now=cho[i];
        }
        }
        sum++;
        if(sum<=k)
        return 1;
        else
        return 0;
    }
    ll ans;
    void hzr(ll l,ll r)
    {
        if(l==r)
        return;
        ll m=(l+r)>>1;
        if(check(m))
        {
        ans=m;
        hzr(l,m);
        }
        else
        {
        hzr(m+1,r);
        }
    }
    int main()
    {
        freopen("chocolate.in","r",stdin);
        freopen("chocolate.out","w",stdout);
        n=gi(),k=gi();
        for(int i=1;i<=n;i++)
        cho[i]=gl();
        hzr(1,100000000000000);
        printf("%lld
    ",ans);
        return 0;
    }

     

     

    PEACE
  • 相关阅读:
    理解OO 思想 架构好一个程序之基石!~
    WP7 ZIP 压缩与解压缩
    Gis LBS 应用 剧本 (自己乱想的)
    PHP 入门 环境搭建
    Android 入门必须知道的 英文缩写
    Android 开发 数据结构理解 队列和栈 分析及实现
    c函数中形参为引用的情况;C++中*a和*&a的区别
    如何在.NET中使用尾递归
    [ProjectEuler.net] 25 找到第一个fib数,数位为1000位
    NFA_DFA
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/7441138.html
Copyright © 2011-2022 走看看