zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    Java 时区转换(UTC+8 到 UTC 等等)
    spring 与 springmvc 的区别和定义
    字符串加密解密(Base64)
    上传视频本地预览问题
    vue 监听store中的数值
    判断对象是否为空
    正则 验证是否包含特殊字符
    js 过滤日期格式
    vue methods computed watch区别
    for + setTimeout
  • 原文地址:https://www.cnblogs.com/littlehb/p/15059927.html
Copyright © 2011-2022 走看看