历届试题 最大子阵
时间限制:1.0s 内存限制:256.0MB
问题描述
给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。
其中,A的子矩阵指在A中行和列均连续的一块。
其中,A的子矩阵指在A中行和列均连续的一块。
输入格式
输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
接下来n行,每行m个整数,表示矩阵A。
接下来n行,每行m个整数,表示矩阵A。
输出格式
输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。
样例输入
3 3
-1 -4 3
3 4 -1
-5 -2 8
-1 -4 3
3 4 -1
-5 -2 8
样例输出
10
样例说明
取最后一列,和为10。
数据规模和约定
对于50%的数据,1<=n, m<=50;
对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。
对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。
一看就像求一个序列中连续和最大的的变形 一维的(只尺法)我感觉也有贪心的味道 从一个数开始连续加 如果为负数了 还有必要往后面加吗?这是就抛弃前面的
这些 从新开始累加 需要两个记录标记 一个存最大值 一个存当前的值 时间O(N) 二位的压缩成一维的就OK了 时间O(N*N*M),大概还要除以2 时间还是不会爆
#include<bits/stdc++.h>
using namespace std;
int ap[550][550],aap[550];
int main(void)
{
int n,m,i,j,k,h;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=1; i<=n; i++)
for(j=1; j<=m; j++)
scanf("%d",&ap[i][j]);
int maxx,total,sum;
total=-5001;
for(k=1; k<=n; k++)
{
for(h=k; h<=n; h++)
{
if(k==h)
{
for(i=1; i<=m; i++) aap[i]=ap[k][i];
}
else
{
for(j=1; j<=m; j++)
aap[j]+=ap[h][j];
}
maxx=-5001;
sum=0;
for(j=1; j<=m; j++)
{
sum+=aap[j];
if(sum>maxx) maxx=sum;
if(sum<0) sum=0;
}
if(total<maxx) total=maxx;
}
}
printf("%d\n",total);
}
}