zoukankan      html  css  js  c++  java
  • 数列分段--二分答案

    洛谷原题
    p1182数列分段

    是刚学二分答案的弱鸡

    不是因为刷最短路的时候碰到通往奥格瑞玛的道路才来学二分的

    是一道非常简单的二分答案(废话

    二分答案,窝的理解就是二分查找加判定,一般适用于求最大的最小值或者最小的最大值之类的,查找答案的区间具有单调性。就是在涵盖答案的区间里二分搜索,用一个judge函数来判断是否满足答案的要求,如果恰好是第一个满足要求的就找到了答案。

    说说这道题,其实一开始窝没看懂上哪搜答案(区间是啥啊)其实手模一遍样例很简单。

    M是大于1小于N的,那么我们至多分成N段至少分成1段,在这两个极端下,前者的最大值必定是这N个正整数中最大的A_i,后者的最大值就是N个数的总和($$A_1$$+(A_2)+...+(A_N)),那么答案一定会是在[(A_i),((A_1)+(A_2)+...+(A_N))]这个区间里!

    既然确定区间了,剩下的就是判定了

    先双手捧上代码

    bool judge(int max){/*判断max是否能作为答案*/
       for(int i = 0; i < n; i++){/*还是"%ni"一遍,会发现其实tim记的就是如果要按max为答案分,能分成几组*/
           if(total+a[i]<=max) total += a[i];/*合起来比max小就是一组*/ 
           else total = a[i],tim++;/*合起来大了就把之前记下的那堆合成一组*/ 
       }
       return tim >= m;/*如果最后分的组多了的话,那么说明目前的max大了,少了就是小了*/ 
        
    }
    

    按照这个返回值,就是max大了返回0,max小了返回1,那么怎么查找也就很明确了

      while(lef<=rig){
            mid = (lef+rig)/2;
            total = 0, tim = 0;
            if(judge(mid)) lef = mid + 1;/*max小了就让中间值成为左端点,右半部分就是我们剩下要搜的区间*/ 
           else rig = mid - 1;/*max大了就让中间值成为右端点,左半部分就是我们剩下要搜的区间*/ 
        }
    

    那么这个题,就AC了!

    全部代码

    #include<bits/stdc++.h>
    using namespace std;
    
    int n,m,a[100100],lef,rig,mid,total,tim;
    
    bool judge(int max){
       for(int i = 0; i < n; i++){
           if(total+a[i]<=max) total += a[i];
           else total = a[i],tim++;
       }
       return tim >= m; 
        
    }
    
    int main(){
        cin>>n>>m;
        for(int i = 0; i < n; i++){
            cin>>a[i];
            rig+=a[i];
            lef = lef > a[i] ? lef: a[i];
        }
        while(lef<=rig){
            mid = (lef+rig)/2;
            total = 0, tim = 0;
            if(judge(mid)) lef = mid + 1;
           else rig = mid - 1; 
        }
        cout<<lef;
        return 0;
    }
    

    谢谢!

  • 相关阅读:
    小禾满月了
    Gitlab-CI使用及.gitlab-ci.yml配置入门一篇就够了
    什么是CLI?
    什么是root帐户?
    Linux 的目录结构是怎样的?
    什么叫 CC 攻击?什么叫 DDOS 攻击?
    什么是 inode ?
    判断一文件是不是字符设备文件,如果是将其拷贝到 /dev 目录下?
    编写 Shell 程序,实现自动删除 50 个账号的功能,账号名为stud1 至 stud50 ?
    请问当用户反馈网站访问慢,如何处理?
  • 原文地址:https://www.cnblogs.com/qmings/p/12099455.html
Copyright © 2011-2022 走看看