动态规划 - OJ1768最大子矩阵

Posted accepted20191024

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划 - OJ1768最大子矩阵相关的知识,希望对你有一定的参考价值。

题目来源:http://noi.openjudge.cn/ch0206/1768/

1768:最大子矩阵

总时间限制: 1000ms;内存限制: 65536kB

描述:
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2

的最大子矩阵是

9 2
-4 1
-1 8

这个子矩阵的大小是15。
输入:
输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[-127, 127]。
输出:
输出最大子矩阵的大小。
来源
翻译自 Greater New York 2001 的试题
————————————————————————————————————————————————
刚拿到这道题的时候是有点懵逼的,因为对于二维结构想不到最优子结构,更想不到状态转移方程。
但是既然二维有困难,那么我们可以先把它转化为一维的结构。

铺垫:先想如何找一行一维数组的最大连续元素和呢?

重点是这个状态转移方程: b[i] = max { b[i-1] + b[i] , b[i] };

若到前一个元素为止的“最优的”累加和为正,则计算到当前元素的累加和时,需要加上先前的部分;反之则不。

 

现在我们来想怎么把二维压缩到一维:

矩阵内的元素为左上角的坐标(x1,y1和右下角的坐标x2,y2)决定。

如果我们暂时定下来目前是找 x1,x2 之间的,垂直长度已为|x2-x1|的矩形的最大面积;

那么既然宽度|x2-x1| 已经定下来了,那么这边枚举出来的矩阵面积,必定是某几连续列的整列和。

把每列的元素和都加起来,a[ym,x1]+……a[ym,x2],即得到了一个一维数组。

再按照前面的铺垫,找到最大最大字段和,即为在|x2-x1|宽度约束下的最大矩形

外面再套两层for循环来枚举不同的 x1,x2 即可

 

以下是AC代码:

 1 #include <iostream>
 2 #include <cmath>
 3 using namespace std;
 4  
 5 int a[105][105];
 6 int b[105]; //算出目前x1-x2行的二维压缩成的一维数组
 7 
 8 int main(){
 9     int N;
10     cin>>N;
11     for(int i=0;i<N;i++){
12         for(int j=0;j<N;j++){
13             cin>>a[i][j];
14         }
15     }
16     int ans=0;
17     for(int i=0;i<N;i++){
18         for(int j=i;j<N;j++){
19             memset(b,0,sizeof(b));
20             for(int p=0;p<N;p++){
21                 for(int q=i;q<=j;q++){
22                     b[p]+=a[q][p];//得到压缩后的一维数组
23                 }
24             }
25             for(int k=0;k<N;k++){
26                 b[k]=max(b[k],b[k]+b[k-1]);
27             }
28             for(int k=0;k<N;k++){
29                 ans=max(ans,b[k]);
30             }
31         }
32     }
33     
34     cout<<ans<<endl;
35     
36     return 0;
37 }

 

 

参考博客:https://www.cnblogs.com/GodA/p/5237061.html

以上是关于动态规划 - OJ1768最大子矩阵的主要内容,如果未能解决你的问题,请参考以下文章

NOI题库 1768最大子矩阵 题解

noi openjudge 1768:最大子矩阵

动态规划---例题4.最大子矩阵和问题

1768:最大子矩阵(NOIP2014初赛最后一题)

openjudge-NOI 2.6基本算法之动态规划 专题题解目录

openjudge1768 最大子矩阵[二维前缀和or递推|DP]