您的位置:首页 > 其它

最大子矩阵【最大连续子串和的衍生】

2014-03-19 22:44 253 查看
最大和

时间限制:1000 ms  |  内存限制:65535 KB
难度:5

描述

给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。 

例子:
0 -2 -7 0 
9 2 -6 2 
-4 1 -4 1 
-1 8 0 -2 
其最大子矩阵为:

9

-4 1 
-1 8 
其元素总和为15。 

输入第一行输入一个整数n(0<n<=100),表示有n组测试数据;

每组测试数据:

第一行有两个的整数r,c(0<r,c<=100),r、c分别代表矩阵的行和列;

随后有r行,每行有c个整数;
输出输出矩阵的最大子矩阵的元素之和。样例输入
1  4 4  0 -2 -7 0   9 2 -6 2   -4 1 -4 1   -1 8 0 -2

样例输出
15

 
最大子矩阵和问题

问题描述:给定一个m行n 列的整数矩阵a,试求矩阵a 的一个子矩阵,使其各元素之和为最大。

分析:用2 维数组a[1 : m][1 : n]表示给定的m行n列的整数矩阵。子数组a[i1 : i2][j1 :
j2]表示左上角和右下角行列坐标分别为(i1, j1)和(i2, j2)的子矩阵,其各元素之和记为:


 (1)

最大子矩阵和问题的最优解即为:



(2)

 



 

 

 

 

(3)

如果令:



 

 


那么

(4)

 

式(4)就是我们熟悉的最大子序列和的问题。

根据以上分析我们可得到最大子矩阵和问题的算法:

Max_Sub_Matrix(m, n, a) //m为行数,n为列数,a为二维矩阵

sum ← 0

b

for i←1 to m

for t←1 to n

do b[t] = 0 //初始化数组b

for j←i to m

do for k←1 to n

b[k] ← b[k] + a[j][k]

max←Max_Sub_List(n, b) //函数返回n个数的序列b的最大子序列的和

if max > sum then sum = max

return sum

下面我们就通过来同学上课提出的一些特殊情况来检验算法的正确性。

1 
2 
3 
1 
-2 
10 
20 
2 
100 
-1 
-2 
3 

-2 
-3 
矩阵a的行m=3,列数n=3,矩阵的元素分布如上图所示。

当i = 1时,初始化数组b,使得
b:



当j = 1时,k从1递增到n,由算法的第8行可得数组b将首先存储矩阵的第一行的各值,即b为:
b:
-2 
10 
20
 

由最大子序列和的函数Max_Sub_List返回该序列的最大子序列的和值为max=30;

当j = 2时,k 从1递增到n,由算法的第8行可得数组b将矩阵a第二行的值分别加到原有各值上,可得数组b为
b:
98 

18 
 

 

同理,由函数Max_Sub_List返回该序列的最大子序列的和值为max=125。

当j = 3时,k从1递增到n,由算法的第8行可得数组b将矩阵a第三行的值分别加到原有各值上,可得数组b为
b:
98 

15 
 

同理,由函数Max_Sub_List返回该序列的最大子序列的和值为max=120。

到此,i的第一次循环结束。

当i = 2时,从新初始化数组b,使得
b:



j = 2时,k从1递增到n,由算法的第8行可得数组b将首先存储矩阵的第二行的各值,即b为:
b:
100 
-1 
-2 
 

 

由函数Max_Sub_List返回该序列的最大子序列的和值为max=100。

j = 3时,k从1递增到n,由算法的第8行可得数组b将矩阵a第三行的值分别加到原有各值上,可得数组b为
b:
100 
-3 
-5 
 

 

由函数Max_Sub_List返回该序列的最大子序列的和值为max=92。

到此,i的第二次循环结束。

当i=3循环结束时,可求出该矩阵的最大子矩阵和值为125。

算法的第7到第9行求出每行i固定,j变化的最大子序列和的最大值,第6行为可能与第i行一起构成子矩阵的行,将其值对应加到第i行,然后求该子序列的最大值。而最外层的循环为分别求出每一行的子序列最大值。

 

说明:最大子序列的解法大家可根据上课介绍的方法使用动态规划法来构造。而大家在网上看到的解法一般不能处理(-1,-2,-3),类似于这种所有元素均为负值的序列,而且也不能够方便的处理返回最小个数的位置。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: