【题目】
给定一个矩阵 matrix,其中矩阵中的元素可以包含正数、负数、和0,返回子矩阵的最大累加和。例如,矩阵 matrix 为:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
拥有最大和的子矩阵为:
9 2
-4 1
-1 8
其和为15。
【分析】
最大子矩阵和可以转化成几行几列的最大子段和问题
即把二维的压缩成一维的问题去解决
a[1][1] a[1][2] ······ a[1][i] ······ a[1][j] ······ a[1][n]
a[2][1] a[2][2] ······ a[2][i] ······ a[2][j] ······ a[2][n]
······
a[q][1] a[q][2] ······ a[q][i] ······ a[q][j] ······ a[q][n]
······
a[p][1] a[p][2] ······ a[p][i] ······ a[p][j] ······ a[p][n]
······
a[n][1] a[n][2] ······ a[n][i] ······ a[n][j] ······ a[n][n]
最大子矩阵和就是矩阵中红色的子矩阵。
将问题转化成取矩阵的第q行到第p行,列取第i列到第j列,将其内(p-q+1)*(j-i+1)个元素和看成一个一位数组a[q][i]+······+a[p][i] , ······ ,a[q][j]+······+a[p][j]的和。这样问题就转化成如何在n*m的矩阵中分离出第q行到第p行,第i列到第j列,于是有代码:
#include<bits/stdc++.h>
using namespace std;
int Maxsub(int a[],int n)
{
int Max=0,temp=0;
for(int i=0;i<n;i++)
{
if(temp>0)
temp+=a[i];
else
temp=a[i];
Max=max(Max,temp);
}
return Max;
}
int main()
{
int n,m;
cin>>n>>m;
int dp[100][100];
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
cin>>dp[i][j];
int arr[100];
int Maxarr=0,Maxmat=0;
for(int i=0;i<n;i++)//从第i行
{
memset(arr,0,sizeof(arr));
for(int j=i;j<n;j++)//到第j行
{
for(int k=0;k<m;k++)
arr[k]+=dp[j][k];
Maxarr=Maxsub(arr,m);
Maxmat=max(Maxmat,Maxarr);
}
}
cout<<Maxmat<<endl;
return 0;
}