最大子阵
详细思路链接:https://www.cnblogs.com/GodA/p/5237061.html
问题描述:
给定一个n×m 的矩阵A,求A 中的一个非空子矩阵,使这个子矩阵中的元素和最大。其中A 的子矩阵指在A 中行和列均连续的一部分。
输入的第一行包含两个整数n,m(1≤n,m≤50),分别表示矩阵 AA 的行数和列数。
接下来n 行,每行m 个整数,表示矩阵Ai,j(−1000≤Ai,j≤1000)。
输出一行,包含一个整数,表示A 中最大子矩阵的元素和。
样例输入
3 3 2 -4 1 -1 2 1 4 -2 2
样例输出
6
代码:
/* 思路剖析: 最大子矩阵 注意任意行列连续 就拿3*3矩阵为例 共有 9 (单个元素) +12(两个元素) +6 (三个元素) +4 (六个元素) +1 (九个元素) =32种子矩阵模式! // 此题的关键就是如何选取。 我们知道矩阵的维数为动态变化过程,但是在挖取子矩阵的过程中,一定是绑定“行”或“列”这个要素。 // 具体举例而言: 对于矩阵 M = {2,-4, 1; -1,2, 1; 4,-2,2 } 单个元素时,我们似乎只要求元素最大值即可; 非单个元素时,我们会考虑行或者列: 两个:(2,-4)或(2,-1)等 三个:(2,-4,1)或(2,-1,4)等 六个:{2,-4,1;-1,2,1}或{2,-4;-1,2;4,-2}等 九个:M 我们发现这样一个规律(行的效果等同于列): 可以定义出一个值动态变化的三维数组。 它的三个值分别对应第i行第k列到第j行第k列的元素和(其中i,j,k 均=0,1,2) 其中 j 的取值由 i 影响 代码细说。 */ #include <iostream> #include <cstring> using namespace std; int n,m; int dp[300][300],arr[300]; int MAX(int a[],int n){ int max=-1000000; for(int i=0;i<n;i++){ int tmpmax=0; for(int j=i;j<n;j++){ tmpmax+=a[j]; if(tmpmax>max)max=tmpmax; } } return max; } int main() { cin>>n>>m; for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { cin>>dp[i][j]; } } int maxsub=-1000000,maxarr=0; for(int i=0;i<n;i++) { memset(arr,0,sizeof(arr)); for(int j=i;j<n;j++) { int k; for(k=0;k<m;k++) { arr[k]+=dp[j][k]; } maxarr=MAX(arr,k);/*在这里wa了好几次,第一次是放在该循环的外面了,第二次发现k写成n了,要是写成n计算的数就变多了*/ if(maxarr>maxsub) maxsub=maxarr; } } cout<<maxsub<<endl; return 0; }