Leetcode 410. Split Array Largest Sum

Problem:

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.

Solution:

  看到极小化极大值的问题,我的第一个想法就是动态规划,一般来说,这类极小化极大值或极大化极小值问题大概率都是用动态规划来做,而且还有一个特性,就是动态规划一般会把一维问题上升到三维的时间复杂度,比如Leetcode 375。照这个思路往下走,如何进行规划呢。首先是维护一个二维数组,dp[i][j]表示在第j个数之前把子数组分为i份的最小的最大值(有点绕,意思是第j个数之前可能有多种分法,每种分法都有一个和最大的子数组,dp[i][j]即所有分法中最小的最大值),因此,如果将第j个数之前把它分为i+1份,则从i到j进行循环(因为第i个数之前不可能分为i份),计算dp[i][t]和sum[j]-sum[t]中的较大值,在这i到j之间寻找这个较大值的最小值赋给dp[i+1][j],代码如下

 1 class Solution {
 2 public:
 3     int splitArray(vector<int>& nums, int m) {
 4         int value = INT_MAX;
 5         int summary = 0;
 6         vector<int> sum(nums.size(),0);
 7         vector<int> dp(nums.size(),INT_MAX);
 8         for(int i = 0;i != nums.size();++i){
 9             summary += nums[i];
10             sum[i] = summary;
11         }
12         for(int i = 0;i != nums.size();++i)
13             dp[i] = sum[i];
14         for(int i = 1;i != m;++i){
15             for(int j = nums.size()-1;j >= i;--j){
16                 value = INT_MAX;
17                 for(int t = i-1;t != j;++t){
18                     value = min(value,max(dp[t],sum[j]-sum[t]));
19                 }
20                 dp[j] = value;
21             }
22         }
23         return dp.back();
24     }
25 };

  然而这道题还没有结束,通过提交效率的直方图我发现有两个距离差的较远的高峰,而且标签还有一个诡异的Binary Search,这说明这道题还有一个二分搜索的解法。首先我们可以断定答案落在区间[max(nums),sum(nums)]之间,所以我们在这个区间内做二分搜索,并判断当结果为pivot时至少可以分为多少部分,找到最小可以满足分为m份的值。

Code:

 1 class Solution {
 2 public:
 3     int splitArray(vector<int>& nums, int m) {
 4         int left = 0;
 5         int right = 0;
 6         for(int i = 0;i != nums.size();++i){
 7             left = max(left,nums[i]);
 8             right += nums[i];
 9         }
10         while(left < right){
11             int pivot = left+(right-left)/2;
12             int count = 1;
13             int sum = 0;
14             for(int i = 0;i != nums.size();++i){
15                 sum += nums[i];
16                 if(sum > pivot){
17                     sum = nums[i];
18                     count++;
19                 }
20             }
21             if(count <= m)
22                 right = pivot;
23             else
24                 left = pivot+1;
25         }
26         return left;
27     }
28 };

原文地址:https://www.cnblogs.com/haoweizh/p/10201421.html

时间: 2024-11-09 10:32:43

Leetcode 410. Split Array Largest Sum的相关文章

410. Split Array Largest Sum

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: Given m satisfies the following cons

410. Split Array Largest Sum 把数组划分为m组,怎样使最大和最小

[抄题]: 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, as

Leetcode: Split Array Largest Sum

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: Given m satisfies the following cons

[LeetCode] Split Array Largest Sum 分割数组的最大值

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:Given m satisfies the following const

动态规划——Split Array Largest Sum

题意大概就是,给定一个包含非负整数的序列nums以及一个整数m,要求把序列nums分成m份,并且要让这m个子序列各自的和的最大值最小(minimize the largest sum among these m subarrays). Note:If n is the length of array, assume the following constraints are satisfied: 1 ≤ n ≤ 10001 ≤ m ≤ min(50, n) Examples: Input:num

Split Array Largest Sum LT410

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. Examples: Input: nums = [7,2,5,10,8] m = 2

leetcode410 Split Array Largest Sum

思路: dp. 实现: 1 class Solution 2 { 3 public: 4 int splitArray(vector<int>& nums, int m) 5 { 6 int n = nums.size(); 7 vector<int> sum(n + 1, 0); 8 for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + nums[i - 1]; 9 vector<vector<int>

LC410. Split Array Largest Sum

把一个数组分成m个连续子数组(不能有空数组),求所有分法中,子数组sum的最大值的最小值. 方法1:容易想到的是动态规划 dp[i][j] = min(max(dp[k-1][j-1], sum[k][i]) 1 <= k <= i, dp[i][j]表示用前i个数字,分成j组,最大和的最小值 time:$O(nnm)$ space:$O(nm)$ class Solution { public: typedef long long ll; ll INF = 1e15; int splitAr

LeetCode 548. Split Array with Equal Sum (分割数组使得子数组的和都相同)$

Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies following conditions: 0 < i, i + 1 < j, j + 1 < k < n - 1 Sum of subarrays (0, i - 1), (i + 1, j - 1), (j + 1, k - 1) and (k + 1, n - 1) should be