题意:就是给你一个矩阵,求出最大子矩阵。最大子矩阵的含义就是该矩阵的元素和最大。
思路:把该问题转化为最大连续子串和问题,即二维转化为一维。假设求出的最大子矩阵为从x行到y行,从第c列到第r列,则该矩阵转化为一维即是从第1列到第n列的所有x行到第y行的元素和的最大连续子串和。这样后,复杂度为n的三次方,在求最大连续子串和的时候用DP就可以了。
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
#define CLR(arr,val) memset(arr,val,sizeof(arr))
const int N = 110;
int n;
int max(int a,int b){
return a>b?a:b;
}
int maxvalue(int vv[N]){
int dp[N];
CLR(dp,0);
dp[0] = vv[0];
for(int i = 1;i < n;++i){
dp[i] = max(vv[i],dp[i-1]+vv[i]);
}
int mmax = 0;
for(int i = 0;i < n;++i)
if(dp[i] > mmax)
mmax = dp[i];
return mmax;
}
int main(){
//freopen("1.txt","r",stdin);
while(scanf("%d",&n) != EOF){
int num[N][N];
int dit[N];
CLR(dit,0);
for(int i = 0;i < n;++i)
for(int j = 0;j < n;++j)
scanf("%d",&num[i][j]);
int ans = 0;
for(int i = 0;i < n;++i){
CLR(dit,0);
for(int j = i;j < n;++j){
for(int k = 0;k <n;++k){
dit[k] += num[j][k];
}
/*for(int z = 0;z < n;z++)
printf("%d ",dit[z]);
cout<<endl;*/
ans = max(ans,maxvalue(dit));
}
}
printf("%d\n",ans);
}
return 0;
}