[蓝桥杯]PREV-26.历届试题_最大子阵

问题描述
  给定一个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。
题目描述

代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #define N 500
 5 
 6 int main(void)
 7 {
 8     int i,j,k,max,sum;
 9     int n,m;
10     int dp[N+1][N+1];
11     
12     memset(dp,0,sizeof(dp));
13     scanf("%d%d",&n,&m);
14     for (i=1 ; i<=n ; i++)
15     {
16         for (j=1 ; j<=m ; j++)
17         {
18             scanf("%d",&k);
19             dp[i][j] = dp[i-1][j] + k;//预处理:同一列中,前i行的和 
20         }
21     }
22     
23     max = -0x3f3f3f3f;
24     for (i=1 ; i<=n ; i++)//确定起始行:i 
25     {
26         for (j=i ; j<=n ; j++)//确定终止行:j
27         {
28             sum = 0;
29             for (k=1 ; k<=m ; k++)//计算j-i行,最大k段和 
30             {                
31                 if (sum >= 0)
32                     sum += dp[j][k]-dp[i-1][k];    //累加k段和 
33                 else
34                     sum = dp[j][k]-dp[i-1][k];    //获得当前位置的值
35                 
36                 max = max>sum?max:sum;
37             }
38         }
39     }
40     printf("%d",max);
41     
42     return 0;
43 }
C解法

解题思路:

关于类似求连续子序列和的问题,可以参考:https://www.cnblogs.com/woxiaosade/p/10327587.html

本题涉及到通过动态规划压缩矩阵,从而变成求最大连续子序列和的问题;

1.首先对记录的数据做预处理,即每次计算同一列下,前n行的和 : dp[ i ][ j ] = dp[ i-1 ][ k ] + 录入值;

2.预处理完毕,即完成了对矩阵压缩成一维数组的操作,然后开始遍历 m 个数字,计算对应的最大连续和

猜你喜欢

转载自www.cnblogs.com/mind000761/p/10613790.html
今日推荐