最大和
时间限制:1000 ms | 内存限制:65535 KB
难度:5
- 描述
-
给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。
例子:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
其最大子矩阵为:9 2
-4 1
-1 8
其元素总和为15。
- 输入
- 第一行输入一个整数n(0<n<=100),表示有n组测试数据;
每组测试数据:
第一行有两个的整数r,c(0<r,c<=100),r、c分别代表矩阵的行和列;
随后有r行,每行有c个整数; - 输出
- 输出矩阵的最大子矩阵的元素之和。
- 样例输入
-
1 4 4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2
- 样例输出
-
15
解题思路:这是一个很基本的模型。求矩阵的最大子矩阵和。这个在最大字段和的基础上,通过暴力枚举x*m大小的子矩阵(将子矩阵化成一行的形式,即求列的前缀和),再套用求子段和的方法,最后得到的就是结果。#include<bits/stdc++.h> using namespace std; const int maxn=105; const int INF=1e9; int a[maxn][maxn]; int pref_sum[maxn]; int n,m; int MaxSubSegSum(){ //最大子段和 int ret=-INF,tmp=0; for(int i=0;i<m;i++){ if(tmp<0){ tmp=pref_sum[i]; }else{ tmp+=pref_sum[i]; } if(tmp>ret){ ret=tmp; } } return ret; } int main(){ int t,i,j,k; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); for(i=0;i<n;i++){ for(j=0;j<m;j++){ scanf("%d",&a[i][j]); } } int ans=-INF; for(i=0;i<n;i++){ //枚举子矩阵第一行位置 memset(pref_sum,0,sizeof(pref_sum)); for(j=i;j<n;j++){ //枚举子矩阵行数 for(k=0;k<m;k++){ pref_sum[k]+=a[j][k]; } int tmp=MaxSubSegSum(); if(tmp>ans) ans=tmp; } } printf("%d ",ans); } return 0; }