• P1182 数列分段 Section II 题解


    题目传送门

    一、为什么可以使用二分,怎么想到的?

    每段和的最大值最小。,提示的很明显,什么最大值最小,最小值最大等等,均可以视为二分答案题。为啥呢?因为二分的本质是区间逼近,这样才能求出极值,不用二分你说用啥?

    二、二分查找的是什么?

    本题查找的肯定是每段和的最大值,逼近的是让它最小。

    三、左右边界值是多少?

    每段和的极限情况:(1)一个数字一段;(2)所有数字在一段里。
    每个数字独自一段的话,最大值就是(max(a[i]))
    所有数字在一段的话,最大值就是(sum(a[i]))

    四、是向左逼近,还是向右逼近?

    求最大值的最小。即向左逼近

    五、check函数的实现

    按东北话来讲,就是:逮着一个往死了加,直到冒了就再开一个房间~
    最终是否符合是题意要求就是: (cnt<=m)

    六、C++代码

    #include <bits/stdc++.h>
    
    using namespace std;
    const int N = 100010;
    int a[N];
    int n, m;
    
    //检查函数
    bool check(int mid) {
        int cnt = 1; //最小一个区间
        int sum = 0; //区间和
        for (int i = 1; i <= n; i++) {
            //区间和计算
            sum += a[i];
            //如果超过了mid值
            if (sum > mid) {
                cnt++; //需要下一个段了~
                sum = a[i];
            }
        }
        //是否符合题意的要求,在m个区间段范围内?
        return cnt <= m;
    }
    
    int l, r;
    
    int main() {
        cin >> n >> m;
        //输入
        for (int i = 1; i <= n; i++) {
            cin >> a[i];
            l = max(l, a[i]);
            r += a[i];
        }
    
        while (l < r) {
            int mid = l + r >> 1;//mid的定义:每段和
            if (check(mid)) r = mid;//向左逼近
            else l = mid + 1;
        }
        //输出大吉
        cout << l << endl;
        return 0;
    }
    
    
  • 相关阅读:
    SQL 里面的COALESCE函数
    php SESSION 不能跨页面传递
    eclipse[日文版] 的SVN 上传步骤
    从一个SVN下载的导入另一个SVN里面
    VB 活动添加item元素
    分享8款精美的jQuery图片播放插件
    java初学者必看经典
    (转载)Java NIO:NIO原理分析(二)
    (转载)Java NIO:NIO概述(一)
    磁盘格式化
  • 原文地址:https://www.cnblogs.com/littlehb/p/15059927.html
Copyright © 2020-2023  润新知