题目描述
有一个包含正数和负数的二维数组。一个子矩阵是指在该二维数组里,任意相邻的下标是1*1或更大的子数组。一个子矩阵的和是指该子矩阵中所有元素的和。本题中,把具有最大和的子矩阵称为最大子矩阵。
例如:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
这个数组的最大子矩阵为:
9 2
-4 1
-1 8
其和为15。
输入
输入包含多组测试数据。每组输入的第一行是一个正整数N(1<=N<=100),表示二维方阵的大小。接下来N行每行输入N个整数,表示数组元素,范围为[-127,127]。
输出
输出最大子阵和。
样例输入
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
样例输出
15
解析:
如果是一维数组找最大子阵,那么就是找一段总和最大的上升子序列。
因此可以将二维数组压缩成一维数组,即将 i 行相加。
代码实现:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int maxs(int *w,int n)
{
int m[110];
int maxn;
maxn=w[0];
m[0]=w[0];
int i;
for(i=1;i<n;i++)
{
if(m[i-1]>0)
m[i]=m[i-1]+w[i];
else
m[i]=w[i];
if(maxn<m[i])
maxn=m[i];
}
return maxn;
}
int main()
{
int a[110][110];
int b[110][110];
int q[110];
int n,i,j,k;
while(cin>>n)
{
for(i=0; i<n; i++)
for(j=0; j<n; j++)
{
cin>>a[i][j];
b[i][j]=a[i][j];
}
for(i=1; i<n; i++)
for(j=0; j<n; j++)
b[i][j]+=b[i-1][j];
int maxn=-999;
for(i=0; i<n; i++)
{
for(j=i; j<n; j++)
{
for(k=0; k<n; k++)
if(i==0)
q[k]=b[j][k];
else
q[k]=b[j][k]-b[i-1][k];
int result=maxs(q,n);
maxn=max(result,maxn);
}
}
cout<<maxn<<endl;
}
return 0;
}