题目简介:
给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组。设计一个算法使得这 m 个子数组各自和的最大值最小。
注意:
数组长度 n 满足以下条件:
- 1 ≤ n ≤ 1000
- 1 ≤ m ≤ min(50, n)
示例:
1 | 输入: |
思路:
动态规划,dp[i][j]代表前i个数字分成j段,所有情况下,其各段和的最大值中的最小值。
首先定义一个sub[i],代表前i个数字的和。
对于dp[i][j],我们可以定义一个k,将i个数分成1 ~ k和k + 1 ~ i,其中1 ~ k包括了前j - 1段,则第j段的数字便为k + 1 ~ i。
所以每次划分,得到的和的最大值为long sum = max(dp[k][j - 1], sub[i] - sub[k]),即前j - 1段的和的最大值的最小值与第j段的和进行比较。
最后dp[i][j]为这些最大值的最小值,即min(dp[i][j], sum)。
最后返回dp[nums.size()][m]即可。
tips:
- 由于
i个数字最多只能分成i段,所以j <= min(i, m)。(即m > nums.size()时返回0即可)。 - 需要使用
long来存储数组,否则会溢出。
代码如下:
1 | class Solution { |