试题 历届试题 最大子阵

 

资源限制
时间限制:1.0s   内存限制:256.0MB
 
问题描述
  给定一个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。

思路

  一开始除了前缀和我就想不到接下来该怎么做了,所以看了一下别人的代码,click here.

  先用前缀和把每行前j个数的和存在a[i][j]里,然后三层循环枚举查找最大子阵和,枚举过程不细说了,通过一个矩阵对着代码想  一想就能懂了.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <algorithm>
 6 #define INF 0x3f3f3f3f
 7 #define zero 1e-7
 8 
 9 using namespace std;
10 typedef long long ll;
11 int n, m, ans=-5000;//单个数不会小于-5000,所以ans作为最大子阵和,最小就是-5000 
12 int a[505][505];
13 
14 int main() {
15     cin>>n>>m;
16     //录入矩阵 
17     for(int i=1; i<=n; i++) {
18         for(int j=1; j<=m; j++) {
19             cin>>a[i][j];
20             a[i][j]+=a[i][j-1];
21         }
22     }
23     for(int i=0; i<=m; i++) {
24         for(int j=i+1; j<=m; j++) {
25             int temp=0;
26             for(int k=1; k<=n; k++) {
27                 temp+=a[k][j]-a[k][i];
28                 ans=max(ans, temp);
29                 temp=max(temp, 0);
30             }
31         }
32     }
33     cout<<ans<<endl;
34     return 0;
35 }

 

posted @ 2020-09-05 17:24  自在逍遥处  阅读(119)  评论(0编辑  收藏  举报