动态规划——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     }

原文地址:https://www.cnblogs.com/messi2017/p/9900027.html

时间: 2024-11-05 14:50:35

动态规划——Split Array Largest Sum的相关文章

Leetcode 410. Split Array Largest Sum

Problem: Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note: If n is the length of array

410. Split Array Largest Sum

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note: Given m satisfies the following cons

Leetcode: Split Array Largest Sum

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note: Given m satisfies the following cons

[LeetCode] Split Array Largest Sum 分割数组的最大值

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note:Given m satisfies the following const

410. Split Array Largest Sum 把数组划分为m组,怎样使最大和最小

[抄题]: Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Note:If n is the length of array, as

Split Array Largest Sum LT410

Given an array which consists of non-negative integers and an integer m, you can split the array into m non-empty continuous subarrays. Write an algorithm to minimize the largest sum among these m subarrays. Examples: Input: nums = [7,2,5,10,8] m = 2

LC410. Split Array Largest Sum

把一个数组分成m个连续子数组(不能有空数组),求所有分法中,子数组sum的最大值的最小值. 方法1:容易想到的是动态规划 dp[i][j] = min(max(dp[k-1][j-1], sum[k][i]) 1 <= k <= i, dp[i][j]表示用前i个数字,分成j组,最大和的最小值 time:$O(nnm)$ space:$O(nm)$ class Solution { public: typedef long long ll; ll INF = 1e15; int splitAr

leetcode410 Split Array Largest Sum

思路: dp. 实现: 1 class Solution 2 { 3 public: 4 int splitArray(vector<int>& nums, int m) 5 { 6 int n = nums.size(); 7 vector<int> sum(n + 1, 0); 8 for (int i = 1; i <= n; i++) sum[i] = sum[i - 1] + nums[i - 1]; 9 vector<vector<int>

Get the largest sum of contiguous subarray in an int array

When I finished reading this problem,I thought I could solve it by scan every single subarray in the array,and the time complexity is cubic.Every subarray could be the eventual one whose sum is the largest,so I did make a conclusion that the best tim