# 0410. Split Array Largest Sum ###### tags: `Leetcode` `Hard` `Dynamic Programming` `Binary Search` Link: https://leetcode.com/problems/split-array-largest-sum/ ## 思路 ### DP ![](https://i.imgur.com/9CFYk6W.png) ### Binary Search By Value 进行```m```的二分搜索,```m```就是代表```nums```分成```k```份后最大自区段的和。 分析:```m```的最小值是```nums```里的最大值;```m```的最大值是数组元素的总和;对于任一个```mid```,另写函数判断是否满足要求。满足要求的话,就继续缩小k来尝试。 如何判断```m```是否可行呢?两个判据: 如果任何```nums[i]>m```,则不可行。 尽可能地合并元素,使得任何子区段的和都不超过```m```,并在遍历的过程中记录这些子区段的数目,超过```k```的话就说明不可行。 ## Code ### DP ```java= class Solution { public int splitArray(int[] nums, int K) { int n = nums.length; int[][] dp = new int[n+1][K+1]; for(int i=1; i<=n; i++) Arrays.fill(dp[i], Integer.MAX_VALUE); for(int i=1; i<=n; i++){ for(int k=1; k<=Math.min(K, i); k++){ int sum = 0; for(int j=i; j>=k; j--){ sum += nums[j-1]; dp[i][k] = Math.min(dp[i][k], Math.max(dp[j-1][k-1], sum)); } } } return dp[n][K]; } } ``` c++ ```cpp= class Solution { public int splitArray(int[] nums, int m) { int n = nums.length; int[] arr = new int[n+1]; for(int i=0; i<n; i++) arr[i+1] = nums[i]; for(int i=1; i<=n; i++) arr[i] += arr[i-1]; int[][] dp = new int[n+1][m+1]; for(int i=1; i<=n; i++) Arrays.fill(dp[i], Integer.MAX_VALUE); for(int i=1; i<=n; i++){ for(int k=1; k<=Math.min(m, i); k++){ for(int j=i; j>=k; j--){ dp[i][k] = Math.min(dp[i][k], Math.max(dp[j-1][k-1], arr[i]-arr[j-1])); } } } return dp[n][m]; } } ``` ### Binary Search By Value ```java= class Solution { public int splitArray(int[] nums, int k) { int start = 0, end = 0; for(int num:nums){ start = Math.max(start, num); end += num; } while(start<end){ int mid = start+(end-start)/2; if(split(nums, mid)>k){ start = mid+1; } else end = mid; } return start; } public int split(int[] nums, int m){ int cnt = 0; for(int i=0; i<nums.length; i++){ int cur = 0; int j=i; while(j<nums.length && cur+nums[j]<=m){ cur += nums[j++]; } i = j-1; cnt++; } return cnt; } } ```