动态规划-最大子矩阵

问题:给一列数n个,求最大连续子序列和(即连续的子序列中和最大的序列)若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素  本文作者 凌风 csdn (iaccepted)

拓展:给一个n*n的矩阵,求其中和最大的子矩阵(即所有子矩阵中和最大的阵)

首先也是从最简单的着手,拿到问题,很容易想到的就是直接爆搜(求所有可能的子序列和并找出最大的即可)时间复杂度为n^2

[cpp] view plain copy

print?

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <limits.h>
  4. #define N 10002
  5. /*
  6. problem:求最大连续子序列的问题dp
  7. time:n^2
  8. */
  9. int main(){
  10. int a[N],i,j,maxx,sum,n,ps,pe;
  11. scanf("%d",&n);
  12. for(i=0;i<n;++i){
  13. scanf("%d",&a[i]);
  14. }
  15. maxx = INT_MIN;//初始为最小整数
  16. for(i=0;i<n;++i){
  17. sum = 0;
  18. for(j=i;j<n;++j){//i,j两个子循环来遍历所有的子序列并计算其和(a[i]加到a[j])
  19. sum += a[j];
  20. if(sum>maxx){//把和大的保留并记录下最大序列的始末位置ps、pe
  21. maxx = sum;
  22. ps = i;
  23. pe = j;
  24. }
  25. }
  26. }
  27. printf("%d %d %d\n",maxx,a[ps],a[pe]);
  28. }

上面的这段代码思路非常的清晰也便于理解,但是数据量大的话时间消耗也会很大,当然ACM的要求肯定是达不到了,现在做时间复杂度为n的算法来解决该问题。

算法基于的思想也很简单,最大连续子序列和的第一个元素不可能是负数,这点很好证明(反证),假设a[i…j]为最大的连续子序列且a[i]为负,那我a[i+1…j]的和将会大于a[i…j]的和,所以与原假设矛盾,这就能推出最大子序列和的第一个元素不可能是负数。得到这个结论我们就可以进一步进行推广,那就是如果一个子序列的和为负数,那么这个序列不可能是最大连续子序列中的开始的一段序列(类似于第一个元素的方法可得到证明即把这段和看做是一个元素)。根据这一思想就可以得到本体线性的算法。

[cpp] view plain copy

print?

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <limits.h>
  4. #define N 10002
  5. int main(){
  6. int a[N],maxx,i,n,sum,ps,pe,ts,te;
  7. scanf("%d",&n);
  8. for(i=0;i<n;++i){
  9. scanf("%d",&a[i]);
  10. }
  11. sum = 0;
  12. maxx = INT_MIN;
  13. for(i=0;i<n;++i){
  14. if(sum<=0){//如果前面的和为负,则前面的序列舍掉从本元素开始重新确定新序列
  15. sum = a[i];
  16. ts = i;
  17. te = i;
  18. }else{//如果前面的和为正,则可能出现在最大序列中,所以要继续累加
  19. sum += a[i];
  20. te = i;
  21. }
  22. if(sum>maxx){//记录下最大子序列和及起始和结束位置
  23. maxx = sum;
  24. ps = ts;
  25. pe = te;
  26. }
  27. }
  28. printf("%d %d %d\n",maxx,a[ps],a[pe]);
  29. return 0;
  30. }

至此,最大连续子序列问题得到解决。

下面记录下最大子矩阵和的求法。

其实最大子矩阵和的算法就是最大连续子序列的一个拓展问题,思路很简单,就是将矩阵先预处理下,按列累加,然后通过三个循环变量来遍历所有的子矩阵,对每个子矩阵以列和为元素转化为n个元素序列求最大连续子序列的问题就可以了。

本文作者 凌风 csdn(iaccepted)

作者博客:http://blog.csdn.Net/iaccepted,欢迎交流

时间: 2024-10-07 11:32:53

动态规划-最大子矩阵的相关文章

HDOJ To The Max 1081【动态规划-详解求最大子矩阵】

To The Max Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9879    Accepted Submission(s): 4762 Problem Description Given a two-dimensional array of positive and negative integers, a sub-rectan

HDU 1081 To the Max 最大子矩阵(动态规划求最大连续子序列和)

Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. I

最大子矩阵,最大连续子数组进阶,动态规划初级,poj1050

题目描述:现给出一个N*N矩阵,要求求出拥有最大和的子矩阵的和. 例如: 这样的一个矩阵,最大子矩阵的和为15: 此题可以让人联想到求最大连续子数组,求最大子数组在上一篇文章中http://www.cnblogs.com/tz346125264/p/7560708.html. 分析:最大子矩阵可以看为求最大连续子数组拓展到二维数组上,因为矩阵的性质同样在横向竖向上需要连续,那么可以想办法将这个二维数组简化为求连续子数组. 思考: 1.要求最大子矩阵,必须保证每个矩阵都被浏览到,为了保证运行时间尽

动态规划[入门]1- 最大子矩阵和

分析 我们已经解决了一维的问题(基础篇中的最大子段和问题),现在变成二维了,我们看看能不能把这个问题转化为一维的问题.最后子矩阵一定是在某两行之间的.假设我们认为子矩阵在第i行和第j列之间,我们如何得到i和j呢,对,枚举.  枚举所有1<=i<=j<=M,表示最终子矩阵选取的行范围. 我们把每一列第i行到第j行之间的和求出来,形成一个数组c,于是一个第i行到第j行之间的最大子矩阵和对应于这个和数组c的最大子段和.于是,我们的算法变为: for i = 1 to M do for j = 

[bzoj1084][SCOI2005]最大子矩阵_动态规划_伪&#183;轮廓线dp

最大子矩阵 bzoj-1084 SCOI-2005 题目大意:给定一个n*m的矩阵,请你选出k个互不重叠的子矩阵使得它们的权值和最大. 注释:$1\le n \le 100$,$1\le m\le 2$,$1\le k\le 10$. 想法:不会...看了数据范围..卧槽?m<=2?????我们就可以进行一个简单的轮廓线dp. 首先,先分m==1和m==2分类讨论,m==1不说了 m==2 令f[k][i][j]是第一列到了i,第二列到了j,已经选取了k个矩形的最大权值. 转移:有3种转移方式:

动态规划 - OJ1768最大子矩阵

题目来源:http://noi.openjudge.cn/ch0206/1768/ 1768:最大子矩阵 总时间限制: 1000ms:内存限制: 65536kB 描述: 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵.比如,如下4 * 4的矩阵 0 -2 -7 09 2 -6 2-4 1 -4 1-1 8 0 -2 的最大子矩阵是 9 2-4 1-1 8 这个子矩阵的大小是15. 输入: 输入是一个N * N的矩阵.输入的第一行给出N

luogu P2258 子矩阵 |动态规划

题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第22.44行和第22.44.55列交叉位置的元素得到一个2 \times 32×3的子矩阵如右图所示. 9 3 3 3 9 9 4 8 7 4 1 7 4 6 6 6 8 5 6 9 7 4 5 6 1 的其中一个2 \times 32×3的子矩阵是 4 7 4 8 6 9 相邻的元素:矩阵中的某个元素与其上下左右四个元素(如果存在的话

集训第五周动态规划 F题 最大子矩阵和

Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this probl

BZOJ 1084 SCOI2005 最大子矩阵 动态规划

题目大意:给出一个矩阵,求在这个矩阵中取出k个不重叠的矩阵的最大和. 思路:怎么做? 这个问题困扰我好几天的时间,终于再一次读题: ... .. ... 2??!! 这尼玛逗我??直接说最多两列不好么?还用矩阵吓唬我? 好吧下次我一定认真看题.. 我的做法比较渣,算出来的时间复杂度是O(m^3*k),但是只有最多3000w,还是可以过的. 状态:f[i][j][k]表示第一列到了第i个格子,第二列到了第j个格子,已经选取了k个矩阵的最大得数. 转移:先把现有的状态向后转移,转移成f[i'][j'