动态规划 - 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

原文地址:https://www.cnblogs.com/Accepted20191024/p/11745232.html

时间: 2024-10-15 04:14:05

动态规划 - OJ1768最大子矩阵的相关文章

动态规划[入门]1- 最大子矩阵和

分析 我们已经解决了一维的问题(基础篇中的最大子段和问题),现在变成二维了,我们看看能不能把这个问题转化为一维的问题.最后子矩阵一定是在某两行之间的.假设我们认为子矩阵在第i行和第j列之间,我们如何得到i和j呢,对,枚举.  枚举所有1<=i<=j<=M,表示最终子矩阵选取的行范围. 我们把每一列第i行到第j行之间的和求出来,形成一个数组c,于是一个第i行到第j行之间的最大子矩阵和对应于这个和数组c的最大子段和.于是,我们的算法变为: for i = 1 to M do for j = 

304. 二维区域和检索 - 矩阵不可变(动态规划)

给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2). 来自leetcode 本题既是一个熟悉class的题目,也是一道简单的动态规划题,子矩阵面积 = 两块面积 - 重复面积 + 右下角面积 收获: 都是一些值得学习的小习惯 1. 特判的时候直接return, 我会经常思考要不要 return 0 def __init__(self,matrix): if not matrix: return 2.动态规划方程,求子

HDOJ To The Max 1081【动态规划-详解求最大子矩阵】

To The Max Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 9879    Accepted Submission(s): 4762 Problem Description Given a two-dimensional array of positive and negative integers, a sub-rectan

HDU 1081 To the Max 最大子矩阵(动态规划求最大连续子序列和)

Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. I

动态规划-最大子矩阵

问题:给一列数n个,求最大连续子序列和(即连续的子序列中和最大的序列)若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素  本文作者 凌风 csdn (iaccepted) 拓展:给一个n*n的矩阵,求其中和最大的子矩阵(即所有子矩阵中和最大的阵) 首先也是从最简单的着手,拿到问题,很容易想到的就是直接爆搜(求所有可能的子序列和并找出最大的即可)时间复杂度为n^2 [cpp] view plain copy print? #include <stdio.h> #include 

最大子矩阵,最大连续子数组进阶,动态规划初级,poj1050

题目描述:现给出一个N*N矩阵,要求求出拥有最大和的子矩阵的和. 例如: 这样的一个矩阵,最大子矩阵的和为15: 此题可以让人联想到求最大连续子数组,求最大子数组在上一篇文章中http://www.cnblogs.com/tz346125264/p/7560708.html. 分析:最大子矩阵可以看为求最大连续子数组拓展到二维数组上,因为矩阵的性质同样在横向竖向上需要连续,那么可以想办法将这个二维数组简化为求连续子数组. 思考: 1.要求最大子矩阵,必须保证每个矩阵都被浏览到,为了保证运行时间尽

[bzoj1084][SCOI2005]最大子矩阵_动态规划_伪&#183;轮廓线dp

最大子矩阵 bzoj-1084 SCOI-2005 题目大意:给定一个n*m的矩阵,请你选出k个互不重叠的子矩阵使得它们的权值和最大. 注释:$1\le n \le 100$,$1\le m\le 2$,$1\le k\le 10$. 想法:不会...看了数据范围..卧槽?m<=2?????我们就可以进行一个简单的轮廓线dp. 首先,先分m==1和m==2分类讨论,m==1不说了 m==2 令f[k][i][j]是第一列到了i,第二列到了j,已经选取了k个矩形的最大权值. 转移:有3种转移方式:

luogu P2258 子矩阵 |动态规划

题目描述 给出如下定义: 子矩阵:从一个矩阵当中选取某些行和某些列交叉位置所组成的新矩阵(保持行与列的相对顺序)被称为原矩阵的一个子矩阵. 例如,下面左图中选取第22.44行和第22.44.55列交叉位置的元素得到一个2 \times 32×3的子矩阵如右图所示. 9 3 3 3 9 9 4 8 7 4 1 7 4 6 6 6 8 5 6 9 7 4 5 6 1 的其中一个2 \times 32×3的子矩阵是 4 7 4 8 6 9 相邻的元素:矩阵中的某个元素与其上下左右四个元素(如果存在的话

集训第五周动态规划 F题 最大子矩阵和

Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this probl