zoukankan      html  css  js  c++  java
  • 数列分段【二分】

    题目大意:

    给出一个数字串,将它分成m个部分,要求每个部分的和的最大值最小。


    思路:

    很明显的二分答案。首先利用前缀和求出前i个数字之和,然后l=1,r=s[n]来二分和的最大值。要注意当任意一个s[i]s[i1]>m那么就必然不成立。


    代码:

    #include <cstdio>
    #include <iostream>
    using namespace std;
    
    int n,m,s[100011],l,r,mid,sum,k;
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&s[i]);
            s[i]+=s[i-1];  //前缀和
        } 
        l=1;
        r=s[n];
        while (l<r)
        {
            mid=(l+r)/2;
            sum=0;
            k=0;
            for (int i=1;i<=n;i++)
            {
                if (s[i]-s[i-1]>mid)  //任意一个数字超过了答案
                {
                    sum=m+1;
                    break;
                }
                if (s[i]-s[k]>mid)  //这一部分超过答案
                {
                    sum++;
                    k=i-1;
                    if (sum>m) break;
                }
            }
            if (sum<m) r=mid;
             else l=mid+1;
        }
        printf("%d\n",r);
        return 0;
    }
  • 相关阅读:
    R的农场 chebnear
    math
    求平面内最近点对
    字符加密 cipher
    CF448C Painting Fence
    CF264B Good Sequences
    洛谷3166 数三角形
    [NOIP2013] 华容道
    [NOIP2013] 货车运输
    [NOIP2013] 积木大赛
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998770.html
Copyright © 2011-2022 走看看