POJ 3273 Monthly Expense(二分搜索巧妙利用)

题意:

一个整型数组,含有 N 个数,将这 N 个数分成连续的 M 段,使得这 M 段每段的和中的最大值最小,输出最小值。

思路:

1. 很容易想到动态规划上面去了 dp[i, k] = min{dp[i, k], max{dp[j, k-1], subsum[j+1, i]}}; 

2. 比划了下,用斜率优化可不可以做,但是感觉时间和空间上面不允许。最终讨论里面有关于二分搜索的解法:

3. 题目要求的是“最大值的下界”,找到最下界:Ai 是数组中的最大值,最上界是:所有的和。根据上、下界二分搜索看中间值能把数组按题意

   分割成几份,最终的时间复杂度为:O(N*log(HIGH-LOW));

 

#include <iostream>

#include <algorithm>

using namespace std;



const int MAXN = 100010;

int n, m, seq[MAXN];



int binarysearch(int low, int high) {

    while (low <= high) {

        int mid = (low + high) / 2;

        int count = 1, sum = 0;

        for (int i = 0; i < n; i++) {

            if (sum + seq[i] <= mid)

                sum += seq[i];

            else 

                sum = seq[i], count += 1;

        }

        if (count > m)

            low = mid + 1;

        else

            high = mid - 1;

    }

    return low;

}



int main() {

    while (scanf("%d%d", &n, &m) != EOF) {

        int maxnum = 0, sum = 0;

        for (int i = 0; i < n; i++) {

            scanf("%d", &seq[i]);

            sum += seq[i];

            maxnum = max(maxnum, seq[i]);

        }

        printf("%d\n", binarysearch(maxnum, sum));

    }

    return 0;

}

你可能感兴趣的:(exp)