zoukankan      html  css  js  c++  java
  • YbtOj例题:二分1 数列分段

    http://noip.ybtoj.com.cn/contest/14/problem/1

    虽然这道题是例题,但是它非常的经典。所以我决定写一写。

    通常,求解”最大值最小“或”最小值最大“一类的问题,都会用到二分算法。但仅凭这一个条件无法确定使用二分算法,下面举几个栗子

    1.

    (这是本题)

     总的分组数目有限制,二分有判定条件,可以二分。  答案转化为二分判定

    2.

    洛谷P4047部落划分

     部落总数有限制,可以二分。 答案转化为二分判定

    3.

    洛谷P4447 [AHOI2018初中组]分组

     虽然总的组数没有限制,但我们可以构造出一个单调上升的序列,p[x]表示第x组接下来需要接上的数的大小,它是单调递增的,我们可以二分 二分查找

    4.

    洛谷P1080国王游戏

    这道题就不能二分,因为总钱数没有限制,我们也构造不出一个单调的帮助我们解题的序列。

    回到这道题

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 5, inf = 0x3f3f3f3f;
    int n, m, a[N];
    int l, r = 0;
    bool check(int x) {
        int s = 0, cnt = 1;
        for (int i = 1; i <= n; i++) {
            if (s + a[i] <= x)
                s += a[i];
            else {
                cnt++;
                s = a[i];
            }
        }
    
        return cnt <= m;
    }
    int main() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            l = max(l, a[i]);
            r += a[i];
        }
        while (l < r) {
            int mid = l + r >> 1;
            if (check(mid))
                r = mid;
            else
                l = mid + 1;
        }
        printf("%d", l);
        return 0;
    }

     还有一个值得我们思考的地方:

    bool check(int x) {
        int s = 0, cnt = 1;
        for (int i = 1; i <= n; i++) {
            if (s + a[i] <= x)
                s += a[i];
            else {
                cnt++;
                s = a[i];
            }
        }
    
        return cnt <= m;
    }

    是return cnt<=m,并用相应的二分形式,还是return cnt>=m并用相应的二分形式呢。

    通过对最优解是奇数还是偶数的讨论,可以得到

    若求最大值,就用小于等于,若求最小值,就用大于等于  maybe

     

    总之, 二分的边界问题非常麻烦,还是要具体问题具体分析。
  • 相关阅读:
    HDOJ 1207 汉诺塔II
    [转]写代码的小女孩
    POJ Subway tree systems
    HDOJ 3555 Bomb (数位DP)
    POJ 1636 Prison rearrangement (DP)
    POJ 1015 Jury Compromise (DP)
    UVA 10003
    UVA 103 Stacking Boxes
    HDOJ 3530 Subsequence
    第三百六十二、三天 how can I 坚持
  • 原文地址:https://www.cnblogs.com/smartljy/p/13433799.html
Copyright © 2011-2022 走看看