码迷,mamicode.com
首页 > 其他好文 > 详细

410. Split Array Largest Sum

时间:2018-11-06 20:56:00      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:bsp   for   note   bin   ssi   stat   more   alc   online   

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays.

Note:
If n is the length of array, assume the following constraints are satisfied:

  • 1 ≤ n ≤ 1000
  • 1 ≤ m ≤ min(50, n)

 

Examples:

Input:
nums = [7,2,5,10,8]
m = 2

Output:
18

Explanation:
There are four ways to split nums into two subarrays.
The best way is to split it into [7,2,5] and [10,8],
where the largest sum among the two subarrays is only 18.

 

Approach #1:  Plan Recursion (Up to Bottom)

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        const int n = nums.size();
        sums_ = vector<int>(n);
        mem_ = vector<vector<int>>(n, vector<int>(m + 1, INT_MAX));
        sums_[0] = nums[0];
        for (int i = 1; i < n; ++i) {
            sums_[i] = nums[i] + sums_[i-1];        // prefix sum
        }
        return helper(nums, n-1, m);
    }
private:
    int helper(const vector<int>& nums, int k, int m) {
        if (m == 1) return sums_[k];        // split one group. 
        if (m > k + 1) return INT_MAX;      // split groups more than the elements.
        if (mem_[k][m] != INT_MAX) return mem_[k][m];       // return the have memeried status
        int ans = INT_MAX;
        for (int i = 0; i < k; ++i) 
            ans = min(ans, max(helper(nums, i, m-1), sums_[k] - sums_[i]));     // calculation minimize largest sum. 
        return mem_[k][m] = ans;
    }
    vector<vector<int>> mem_;
    vector<int> sums_;
};

Runtime: 116 ms, faster than 2.38% of C++ online submissions for Split Array Largest Sum.

 

Approach #2: DP (Bottom to Up)

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        const int n = nums.size();  // if I don‘t use const it will not compile successfully.
        vector<int> sum(n+1);
        vector<vector<int>> dp(m+1, vector<int>(n, INT_MAX));
        sum[0] = nums[0];
        for (int i = 1; i < n; ++i) 
            sum[i] = sum[i-1] + nums[i];
        for (int i = 0; i < n; ++i) 
            dp[1][i] = sum[i];      // the status with only one group;
        for (int i = 2; i <= m; ++i) {
            for (int j = i-1; j < n; ++j) {
                for (int k = 0; k < j; ++k) {
                    dp[i][j] = min(dp[i][j], max(dp[i-1][k], sum[j] - sum[k]));
                }
            }
        }
        return dp[m][n-1];
    }
};
Runtime: 116 ms, faster than 2.38% of C++ online submissions for Split Array Largest Sum.

 

Approach #3: Binary Search:

class Solution {
public:
    int splitArray(vector<int>& nums, int m) {
        int l = 0, r = 0;
        for (auto& num : nums) {    // if don‘t use auto& it won‘t compile successfully.
            l = max(l, num);
            r += num;        // the answer must exsit bewteen in the l and r.
        }
        while (l <= r) {
            int mid = l + (r - l) / 2;
            if (canSplit(nums, m, mid))
                r = mid - 1;
            else 
                l = mid + 1;
        }
        return l;
    }
private:
    bool canSplit(vector<int>& nums, int m, int mid) {
        int c = 1;
        int sum = 0;
        for (auto& num : nums) {
            sum += num;
            if (sum > mid) {
                c++;
                sum = num;
            }
        }
        return c <= m;
    }
};

Runtime: 4 ms, faster than 49.91% of C++ online submissions for Split Array Largest Sum.

 

410. Split Array Largest Sum

标签:bsp   for   note   bin   ssi   stat   more   alc   online   

原文地址:https://www.cnblogs.com/ruruozhenhao/p/9917804.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!