题目
题解
解法一 二维动态规划
class Solution {
public:
int splitArray(vector<int>& nums, int k) {
int N = nums.size();
int subsum[N];
for(int i = N - 1; i >= 0 ;i--)
{
subsum[i] = (i == N - 1? nums[i] : subsum[i + 1] + nums[i]);
}
int dp[N][k];
for(int i = 0; i < N; i++)
{
for(int j = 0; j < k; j++)
{
dp[i][j] = INT_MAX;
if(j == 0)
{
dp[i][j] = (i == 0 ? nums[i] : dp[i - 1][j] + nums[i]);
cout<<dp[i][j]<<endl;
continue;
}
for(int l = 0; l < i; l++)
{
dp[i][j] = min(dp[i][j], max(dp[l][j - 1], i == N - 1 ? subsum[l + 1] : subsum[l + 1] - subsum[i + 1]));
}
cout<<dp[i][j]<<endl;
}
}
return dp[N - 1][k - 1];
}
};
解法二——二分查找
class Solution {
public:
int splitArray(vector<int>& nums, int k) {
//二分查找
int arrsum = 0;
int arrmax = 0;
int N = nums.size();
for(int i = 0; i < N; i++)
{
arrmax = max(arrmax, nums[i]);
arrsum += nums[i];
}
int l = arrmax;
int r = arrsum;
while(l <= r)
{
int m = (l + r) >> 1;
if(process(nums, k, m))
{
r = m - 1;
}
else
{
l = m + 1;
}
}
return l;
}
bool process(vector<int>& nums, int k, int m)
{
int cnt = 1;
int cursum = 0;
for(int i = 0; i < nums.size(); i++)
{
cursum += nums[i];
if(cursum > m)
{
cursum = nums[i];
cnt++;
}
if(cnt > k) return false;
}
return true;
}
};
总结
看到题目中出现字样:“将这个数组分成 m 个非空的连续子数组”,就可以尝试去构建类似的动态规划。
看到题目中出现字样:“使得*******最大值最小”,可以尝试二分查找。