动态规划_最大子数组|||_1
来源:互联网 发布:数据库去除重复记录 编辑:程序博客网 时间:2024/06/05 02:38
1. 【问题描述】 最大子数组|||
2. 【思路】 参考:LintCode:Maximum Subarray III
假设给定数组共有N个元素,需要找到K个不重合的子数组使其和最大。令符号(i, j)表示在数组前i个元素中找到j个不重合的和最大的子数组的和,符号[a,b]表示在子数组nums[a,a+1,...,b]中找到一个最大子数组,返回最大子数组的和。则有:
(i, j)=max{ (q, j),(p, j-1)+[p+1, i], 其中j<=q<=i-1,j-1<=p<=i-1}
下面以N=6,K=4为例具体说明.首先构建二维数组dpk
(1,1)
(2,1) (2,2)
(3,1) (3,2) (3,3)
(4,2) (4,3) (4,4)
(5,3) (5,4)
(6,4)
(6,4)即为所求.根据(i, j)的表达式可以写出:
(1,1)=nums[0];
(2,2)=(1,1)+[2,2];
(3,2)=max{(2,2),(2,1)+[3,3],(1,1)+[2,3]};
(4,2)=max{(2,2),(3,2),(3,1)+[4,4],(2,1)+[3,4],(1,1)+[2,4]};
(3,3)=(2,2)+[3,3];
(4,3)=max{(3,3),(3,2)+[4,4],(2,2)+[3,4]};
(5,3)=max{(3,3),(4,3),(4,2)+[5,5],(3,2)+[4,5],(2,2)+[3,5]};
观察(2,2)与(3,2)的表达式可以发现:(2,2)=(1,1)+[2,2]<=(1,1)+[2,3],所以(3,2)的表达式可以改写为:
(3,2)=max{(2,1)+[3,3],(1,1)+[2,3]};
同理可以改写后面的表达式。基于此可以改写(i, j)的表达式:
(i, j)=max{ (p, j-1)+[p+1, i], 其中j-1<=p<=i-1}
观察上述(1,1)到(5,3)的表达式发现,加粗部分重复出现,所以可以用一个二维数组保存[a,b]的值避免重复计算.
下面的代码中,过程maxBE(nums,beg,end,dp1)计算[beg,end],其中二维数组dp1保存[beg,end]的值避免重复计算
3. 【代码】
class Solution {public: /** * @param nums: A list of integers * @param k: An integer denote to find k non-overlapping subarrays * @return: An integer denote the sum of max k non-overlapping subarrays */ int maxBE(vector<int> &nums,int beg,int end,vector<vector<int>> &dp1) { if(dp1[beg+1][end+1]!=INT_MIN) { return dp1[beg+1][end+1]; } if(beg==end) { dp1[beg+1][end+1]=nums[beg]; return dp1[beg+1][end+1]; } int mid=beg+(end-beg)/2; int i=mid-1,left=nums[mid],ls=left; while(i>=beg) { ls+=nums[i]; left=left>=ls?left:ls; i--; } int j=mid+2,right=nums[mid+1],rs=right; while(j<=end) { rs+=nums[j]; right=right>=rs?right:rs; j++; } int left_sum=maxBE(nums,beg,mid,dp1),mid_sum=left+right,right_sum=maxBE(nums,mid+1,end,dp1); dp1[beg+1][end+1]=(left_sum>=right_sum?left_sum:right_sum)>=mid_sum?(left_sum>=right_sum?left_sum:right_sum):mid_sum; return dp1[beg+1][end+1]; } int maxSubArray(vector<int> nums, int k) { // write your code here int N=nums.size(); if(N==0||k<=0||N<k) { return -1; } vector<vector<int>> dpk(N+1,vector<int>(k+1,INT_MIN)); vector<vector<int>> dp1(N+1,vector<int>(N+1,INT_MIN)); for(int i=1;i<=N+1-k;++i) { dpk[i][1]=maxBE(nums,0,i-1,dp1); } for(int j=2;j<=k;++j) { for(int i=j;i<=N+j-k;++i) { for(int p=j-1;p<=i-1;++p) { dpk[i][j]=dpk[i][j]>=(dpk[p][j-1]+maxBE(nums,p,i-1,dp1))?dpk[i][j]:(dpk[p][j-1]+maxBE(nums,p,i-1,dp1)); }//for }//for }//for return dpk[N][k]; }};
- 动态规划_最大子数组|||_1
- 动态规划_最大子数组||_1
- 分而治之_最大子数组_1
- 动态规划 最大子数组
- 动态规划_最长公共子序列_1
- 子数组最大和 动态规划求解
- 最大子数组问题【动态规划】
- 动态规划之最大子数组
- 动态规划——最大子数组
- 最大子数组之和(动态规划)
- 动态规划-----最大子数组问题等
- 最大子数组求法--动态规划
- 动态规划-最大连续乘积子数组
- 动态规划-最大子数组和问题
- 动态规划-最大子数组和问题
- 动态规划——数组最大子数组和
- 动态规划——数组最大子数组和 收藏
- 动态规划——数组最大子数组和
- 雌性激素过高怎么办?
- Hibernate学习笔记(五)——多对多映射
- 【Search&String Algorithm Training】Xiper的奇妙历险(1)
- Medium 91题 Decode Ways
- 用flask开发个人博客(22)—— 使用Flask-Migrate实现数据库的更新
- 动态规划_最大子数组|||_1
- ROS源码修改(使用overlaying机制)
- JS中日期方法setMonth的问题
- LaTeX实战经验:配置LaTeX使用环境
- Poedu_C语言_lesson19_20160920_循环
- 冒泡排序法
- Java中的基本数据类型
- 活动(Activity)的生命周期
- LaTeX实战经验:标点符号注意点