题目简介:
给定一个非负整数数组和一个整数 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 { |