题目描述:给定一个二维矩阵包含正负数,求子矩阵中的和的最大值。
例如:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
最大值为: 15 =
9 2
-4 1
-1 8
解题思路: [枚举上下界,转化为一维最大子序列和]
由一维最大子序列和推广至二维: 假设我们已经知道最大子矩阵所在的高度(行)的上界和下界(起点行号和终点行号,eg [first,last]),然后我们再将相应上下界中每一列的和
求出来,保存在数组b[i]中,这样就变成了求一维数组的最大子序列和的问题。
PS: 在求每列之和时,可以用一个小技巧。对于某一上界 a_first, 不同的下界 b_first 对应的每列之和 b[] 都可以由上一个枚举的下界b_first - 1中的b[] 加上当前的值得到。
int max_sum(int ar[],int n) //一维最大子序列和 { int thissum = 0, maxsum = INT_MIN; for (int i = 0;i < n;++i) { thissum += ar[i]; if (thissum < 0) { thissum = 0; } if (thissum > maxsum) { maxsum = thissum; } } return maxsum; } int main() { int mat[100][100]; //输入二维矩阵 int n; int b[100]; //保存相应的和 int maxx = INT_MIN; int temp; cin>>n; for (int i = 0;i < n;++i) { for (int j = 0;j < n;++j) { cin>>mat[i][j]; } } for (int i = 0;i < n;++i) //枚举上下界 i为上界 { memset(b,0,sizeof(b)); //b清零 因为不同上界对应的 列和 不一样 for (int j = i;j < n;++j) //枚举下界 j [i,j] { for (int k = 0;k < n;++k) //求相应的列和 对于同一上界i 不同下界j b[j]总是通过上一个b[j-1]得到 { b[k] += mat[j][k]; //b[j] = b[j - 1] + mat[j][] } temp = max_sum(b,n); //求上下界[i,j]中的最大子序列和 if (temp > maxx) { maxx = temp; } } } cout<<maxx<<endl; return 0; }