leetcode 410. 分割数组的最大值——(每日一难day30)

410. 分割数组的最大值

给定一个非负整数数组 nums 和一个整数 m ,你需要将这个数组分成 m 个非空的连续子数组。

设计一个算法使得这 m 个子数组各自和的最大值最小。

示例 1:

输入:nums = [7,2,5,10,8], m = 2
输出:18
解释: 一共有四种方法将 nums 分割为 2 个子数组。
其中最好的方式是将其分为 [7,2,5] 和 [10,8] 。 因为此时这两个子数组各自的和的最大值为18,在所有情况中最小。

示例 2:

输入:nums = [1,2,3,4,5], m = 2
输出:9

示例 3:

输入:nums = [1,4,4], m = 3
输出:4

提示:

1 <= nums.length <= 1000
0 <= nums[i] <= 1e6
1 <= m <= min(50,nums.length)

解析:

  • 将问题转化:在前边所有数字的基础上添加一个元素对结果产生的影响。例如:枚举到 7 2 5 8 10中的8时,转化为在7 2 5的基础上添加一个8会结果产生影响。
  • 以8为结尾的子数组可能为8 ,8 5,8 5 2,8 5 2 7,如果m=3,可以怎么分配,这时就枚举8结尾的四个子数组作为第1组,让剩余数字产生剩下的2组。
  • 8自身结合作为一组,那么就需要7 2 5产生两组。
  • 8 5 作为一组,需要7 2 产生两组
  • 8 5 2作为一组 ,7不可能产生两组所以枚举结束。
  • 接下来加入10这个元素,m=3
    以10结尾产生子数组为:10 ,10 8 ,10 8 5,10 8 5 2,10 8 5 2 7
    -10作为一组,则7 2 5 8需要组成2组
    -10 8作为一组,则7 2 5需要组成2组(子问题添加8的时候已经出现)
    -10 8 5作为一组,则7 2组成2组(添加8的时候也出现了)
    -10 8 5 2 作为一组,则7组成2组(不可能枚举结束)

我们用f[i][j]表示,以第 i 个数字为结尾时产生 j 组时,这 j 个子数组各自和的最大值最小为f[i][j].

code

class Solution {
public:
    // 每个元素作为第m个子序列的最后一个元素的最大值最小值
    int splitArray(vector<int>& nums, int m) {
        int n=nums.size();
        // f[0][i],f[i][0]不使用,防止越界,
        //直接用f[i][j]表示以第i个元素结尾,分为j组时,各组最大的值最小的值
        int f[n+1][m+1];
        memset(f,0,sizeof(f));
        // 只有一组情况
        for(int i=1;i<n+1;i++){
            f[i][1]=nums[i-1]+f[i-1][1];
        }
        // 枚举每个元素
        for(int i=1;i<=n;i++){
        	// 枚举以当前元素结尾产生的组数
            for(int j=2;j<=m;j++){
            	// 以当前i元素结尾,产生j组时各组最大值最小
                int tmp=0,tmp2=INT_MAX;
                // 元素i结尾最多可以结合i个元素
                    for(int k=i;k>0;k-- ){
                    tmp+=nums[k-1];
                    // 如果需要的组数>剩余数字数
                    if(j-1>k-1) break;
                    // 前k-1个元素,产生j-1组的最大元素,
                    //与最后一组的最大值
                    int a=max(tmp,f[k-1][j-1]);
                    // 枚举所有与第i个元素结合情况,取最小值
                    tmp2=min(tmp2,a);
                }
                f[i][j]=tmp2;
            }
        }
        return f[n][m];
    }
};

版权声明:本文为weixin_42051691原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。