最大子矩阵和
输入
第1行:M和N,中间用空格隔开(2 <= M,N <= 500)。 第2 - N + 1行:矩阵中的元素,每行M个数,中间用空格隔开。(-10^9 <= M[i] <= 10^9)
输出
输出和的最大值。如果所有数都是负数,就输出0。
输入示例
3 3 -1 3 -1 2 -1 3 -3 1 2
输出示例
7
分析:
把每一列第i行到第j行之间的和求出来,形成一个数组,于是一个第i行到第j行之间的最大子矩阵和对应于这个和数组的最大子段和。(这样就化为一维的了)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[510][510];
int dp[510];
int main()
{
int n ,m ;
scanf("%d %d",&m,&n);//注意输入顺序,坑。。。
int flag = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
scanf("%d",&a[i][j]);
if(a[i][j] > 0) //判断是否全部为负值
flag = 1;
}
int sum, ans = 0;
for(int i = 1; i <= n; i++) // 每一行、每一列顺序相加
for(int j = i; j <= n ; j++)
{
sum = 0; //转换为一维求最大子段和,每一次都要初始化
for(int k = 1 ; k <= m; k++)
{
if(i == j)
{
dp[k] = a[i][k];
}
else
{
dp[k] = dp[k] + a[j][k];
}
sum += dp[k];
ans = max(ans , sum);
if(sum < 0 )
sum = 0;
}
}
if(flag)
printf("%d\n",ans);
else
printf("0\n");
return 0;
}