本文共 1125 字,大约阅读时间需要 3 分钟。
问题描述
给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。其中,A的子矩阵指在A中行和列均连续的一块。
输入格式 输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。 接下来n行,每行m个整数,表示矩阵A。 输出格式 输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。 样例输入 3 3 -1 -4 3 3 4 -1 -5 -2 8 样例输出 10 样例说明 取最后一列,和为10。 数据规模和约定 对于50%的数据,1<=n, m<=50; 对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。算是在线算法的二维化,先预处理每列的区间和,再通过枚举行区间,对每个行区间,找出每列的连续和,通过在线算法找最大的那个连续列的值,这个连续列和行区间就是一个最大子矩阵。
写的时候在线算法理解不精,错了几个数据。#include#include #include #include #include #include #include #include #include #include #define INF 0x3f3f3f3f#define MAXN 505#define Mod 1000000007using namespace std;long long a[MAXN][MAXN],sum[MAXN][MAXN],tmp[MAXN];int main(){ memset(sum,0,sizeof(sum)); int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) { scanf("%I64d",&a[i][j]); sum[i][j]=sum[i-1][j]+a[i][j]; } long long ans=a[1][1]; for(int i=0;i<=n;++i) //注意从0开始 { for(int j=i+1;j<=n;++j) //枚举i~j行之间的矩阵元素 { for(int k=1;k<=m;++k) tmp[k]=sum[j][k]-sum[i][k]; long long num=0; for(int k=1;k<=m;++k) //在线算法 { num+=tmp[k]; if(num>ans) ans=num; if(num<0) num=0; } } } cout< <
转载地址:http://focvb.baihongyu.com/