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:
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.
解法: 求一些最大值的最小值或一些最小值的最大值,是DP的关键词,所以想到DP。这道题的关键是想到让最后的元素分为一组,之前的元素分成 j - 1 组。
0 1 2 3 0 0 0 0 0 1 7 0 7 ++ ++ 2 2 0 9 3 5 0 14 4 10 0 24 1. dp[i][j]: first i elements, split into j groups, minimal of larget sum among the groups. 2. init: dp[i][j]: ++ dp[i][1]: first i elements 1 group, sum. dp[i][0]: 0 dp[0][i]: 0 3. dp[i][j]: e.g. dp[4][3]: 7 2 5 10 into 3 groups的答案 即最后的元素分为一组,之前的元素分成2组的所有答案的最小 - min((i),(ii),(iii)) i) 7 | 2 5 10 max(dp[1][2], sum(2,5,10)) (dp[1][2]: invalid, continue) ii) 7 2 | 5 10 max(dp[2][2], sum(5,10)) iii) 7 2 5 | 10 max(dp[3][2], sum(10)) formula: dp[i][j] = min{max(dp[k][j - 1], sum(k+1,i))} for k = [1,i-1]
1 public int splitArray(int[] nums, int m) { 2 int[][] dp = new int[nums.length + 1][m + 1]; 3 for (int i = 0; i < dp.length; i++) { 4 Arrays.fill(dp[i], Integer.MAX_VALUE); 5 } 6 // init 7 for (int i = 0; i < dp.length; i++) { 8 dp[i][0] = 0; 9 } 10 for (int i = 0; i < dp[0].length; i++) { 11 dp[0][i] = 0; 12 } 13 for (int i = 1; i < dp.length; i++) { 14 dp[i][1] = dp[i - 1][1] + nums[i - 1]; 15 } 16 17 for (int i = 2; i < dp.length; i++) { 18 for (int j = 2; j < dp[0].length; j++) { 19 int ans = Integer.MAX_VALUE; 20 int totalSum = dp[i][1]; // for calculating sum(k+1,i). totalSum = sum[0, i] 21 int cumSum = 0; // for calculating sum(k+1,i). cumSum of first k.
23 for (int k = 1; k <= i - 1; k++) { 24 cumSum += nums[k - 1]; // outside, no matter what, add curSum 25 if (dp[k][j - 1] != Integer.MAX_VALUE) { 26 ans = Math.min(ans, Math.max(dp[k][j - 1], totalSum - cumSum)); 27 } 28 } 29 30 dp[i][j] = ans; 31 32 } 33 } 34 return dp[dp.length - 1][dp[0].length - 1]; 35 }