zoukankan      html  css  js  c++  java
  • 动态规划——Split Array Largest Sum

    题意大概就是,给定一个包含非负整数的序列nums以及一个整数m,要求把序列nums分成m份,并且要让这m个子序列各自的和的最大值最小(minimize the largest sum among these m subarrays)。
    Note:
    If n is the length of array, assume the following constraints are satisfied:
    1 ≤ n ≤ 1000
    1 ≤ m ≤ min(50, n)
    Examples:
    Input:
    nums = [7,2,5,10,8]
    m = 2
    Output:
    18
    Explanation:
    There are four ways to split nums into two subarrays.
    The best way is to split it into [7,2,5] and [10,8],
    where the largest sum among the two subarrays is only 18.
    状态:dp[j][i]就是简单的缩小题目的规模,把j长的序列分成i个连续的子序列,子序列和的最大值中的最小值。
    状态转移方程:每次我们只关注整个序列中最后一个元素加入时对dp值的影响,由于是要分成连续的序列,所以最后一个元素只能与它前面的若干元素组成子序列,需要一个for来枚举包含最后一个元素的子序列的情况,例如我现在要求dp[j][i],在放入最后一个元素nums[j]时,设klen为第i个连续子序列的长度,这个子序列的和为
    dp[nums.size][1]-dp[nums.size-klen][1],而前nums-klen个元素组成的i-1个连续子序列和的最大值的最小值为dp[nums.size][i-1]已经在前面的计算过程中完成了计算,易知dp[j][i] = min(max(dp[nums.size][1]-dp[nums.size-klen][1],dp[nums.size][i-1])),这个题可以很明显的看出动态规划的最优子结构
    不过为了方便起见,先将所有的dp[j][1]计算出来,计算很简单也好理解,就是for循环叠加,不过如果单纯用int数组的话可能越界,比如:[1,2147483647],会在dp数组中出现-2147483648这样的元素。由于输入样本都是整数,可以使用double数组,返回的结果用int强制转换即可
     
     1     public int splitArray(int[] nums,int m) {
     2         int nlen = nums.length;
     3         int[]num = new int[nlen+1];
     4         double[][]dp = new double[nlen+1][m+1];
     5         double temp = 0;
     6         num[0] = nums.length;
     7         for(int i = 1;i<=nlen;i++)
     8             num[i] = nums[i-1];
     9         for(int i = 0;i<=nlen;i++)
    10             dp[i][0] = 0;
    11         for(int i = 0;i<=m;i++)
    12             dp[0][i] = 0;
    13         for(int i = 1;i<=m;i++) {
    14             for(int j = i;j<=nlen;j++) {
    15                 if(i==1)dp[j][i] = dp[j-1][i]+num[j];
    16                 else {
    17                     dp[j][i] = dp[nlen][1];
    18                     for(int k = i-1;k<j;k++) {
    19                         temp = dp[k][i-1]>(dp[j][1]-dp[k][1])?dp[k][i-1]:(dp[j][1]-dp[k][1]);
    20                         dp[j][i] = dp[j][i]<temp?dp[j][i]:temp;
    21                     }
    22                 }
    23             }
    24         }
    25         
    26         for(int i = 1;i<=m;i++) {
    27             for(int j = 1;j<=nlen;j++) 
    28                 System.out.print(dp[j][i]+" ");
    29             System.out.println();
    30         }
    31         
    32         return (int) dp[nlen][m];
    33     }
  • 相关阅读:
    go语言第一问:在其他地方执行编译go语言程序,结果会在哪个地方产生?
    ip地址获取无效,自己修改ip地址
    linux和windows双向互通的压缩包格式zip
    在notepad++中tab和空格的区别
    Django ----- app 和 ORM的操作和介绍
    Mysql --- 索引
    Mysql --创建用户和授权,备份
    Mysql --数据的增删改
    Mysql -- 外键的变种 三种关系
    Mysql -- 完整性约束
  • 原文地址:https://www.cnblogs.com/messi2017/p/9900027.html
Copyright © 2011-2022 走看看