NOI题库 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]。
 
输出
 
输出最大子矩阵的大小。
 
样例输入
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
 
样例输出
15
 
 
———————————————————————————————————————
 
 
分析
最初看到这道题时,我完全不知道怎么DP,只能想到暴力算法,这道题的最暴力想法就是枚举,但是这个想法的时间复杂度达到O(N^4),当数据较大时无法承受,经大神指点得知,可以使用动态规划解决这个问题。那么,怎么用动态规划呢?
最初学DP时,有一个求最大子段和的问题,可以通过DP解决,最大子矩阵只是最大子段和在二维中的扩展,为了能继续使用这种方法,我们需要将这个矩阵降维处理,降维操作如下图:
 
这是样例中4*4的矩阵,红色框中是进行降维操作的矩阵

 
 
 降维的操作很简单,只需要将同一列的加和,就能得到目标序列,我们可以使用前缀和思想来优化这个操作。
 
通过这个操作可以将二维矩阵降维,随后就可以用区间DP的方法解决这个最大子矩阵的问题。
 
代码如下:

 #include "cstdio"
#include "cstring"
#include "algorithm"
#include "cmath"
using namespace std ; int gmax( int a , int b)//求最大值
{
return a > b ? a : b ;
} int best[], temp[]; int tmp[][], pr[][]; void Init ( int n )
{
for( int i = ; i <= n ; ++i )pr[][i] = tmp[][i] ;//pr[]数组用前缀和思想
for(int i = ; i <= n ; ++i )
for (int j = ; j <= n ; ++j )
pr[i][j] = pr[i - ][j] + tmp[i][j] ;//计算前缀和
return ;
} int solve ( int *a , int N)
{ memset ( best , , sizeof(best));//best数组表示以i为结尾的最大子序列和
int ans = - ;
for ( int i = ; i <= N ; ++i)
{
if ( best[i - ] + a[i] > a[i])
{
best[i] = best[i - ] + a[i] ;//DP方程
}
else
{
best[i] = a[i] ;//DP方程
}
}
for ( int i = ; i <= N ; ++i )ans = gmax( ans , best[i]);//求出best数组中的最大值,即最大子序列和
return ans ;
} int main ( )
{
int ans = - , n;
scanf("%d", &n);
for(int i = ; i <= n ; ++i )
{
for (int j = ; j <= n ; ++j )
{
scanf("%d", &tmp[i][j]);
}
}
Init ( n );//预处理
for ( int i = ; i <= n ; ++i)
{
for ( int j = i ; j <= n ; ++j )
{
memset( temp , , sizeof(temp));
for ( int k = ; k <= n ; ++k )
{
temp[k] = pr[j][k] - pr[i - ][k];//temp数组是降维后的数组
}
ans = gmax(solve ( temp , n) , ans );//求出最大值
}
}
printf("%d\n", ans);
return ;
}
——————————————————————————————————————
(完)
 

NOI题库 1768最大子矩阵 题解的更多相关文章

  1. NOI题库刷题日志 (贪心篇题解)

    这段时间在NOI题库上刷了刷题,来写点心得和题解 一.寻找平面上的极大点 2704:寻找平面上的极大点 总时间限制:  1000ms  内存限制:  65536kB 描述 在一个平面上,如果有两个点( ...

  2. NOI题库 09:图像旋转翻转变换

    NOI题库开始的题,也是略水,当然也是大水,所以彼此彼此 09:图像旋转翻转变换 总时间限制: 1000ms 内存限制: 65536kB 描述 给定m行n列的图像各像素点灰度值,对其依次进行一系列操作 ...

  3. NOI题库-小学奥赛QwQ

    今天Loli教育我们让我们来看看NOI题库的奥赛部分,不过,为何是小学的( ⊙ o ⊙ )啊!感觉智商被各种侮辱. 余数相同问题: 描述 已知三个正整数 a,b,c. 现有一个大于1的整数x,将其作为 ...

  4. NOI 题库 9272 题解

    9272   偶数个数字3 描述 在所有的N位数中,有多少个数中有偶数个数字3? 输入 一行给出数字N,N<=1000 输出 如题 样例输入 2 样例输出 73 Solution : 令f ( ...

  5. NOI 题库 8471 题解

    8471   切割回文 描述 阿福最近对回文串产生了非常浓厚的兴趣. 如果一个字符串从左往右看和从右往左看完全相同的话,那么就认为这个串是一个回文串.例如,“abcaacba”是一个回文串,“abca ...

  6. noi题库(noi.openjudge.cn) 1.7编程基础之字符串T31——T35

    T31 字符串P型编码 描述 给定一个完全由数字字符('0','1','2',-,'9')构成的字符串str,请写出str的p型编码串.例如:字符串122344111可被描述为"1个1.2个 ...

  7. noi题库(noi.openjudge.cn) 1.7编程基础之字符串T21——T30

    T21:单词替换 描述 输入一个字符串,以回车结束(字符串长度<=100).该字符串由若干个单词组成,单词之间用一个空格隔开,所有单词区分大小写.现需要将其中的某个单词替换成另一个单词,并输出替 ...

  8. NOI题库192 生日蛋糕

    192:生日蛋糕 总时间限制: 5000ms 内存限制: 65536kB 描述 7月17日是Mr.W的生日,ACM-THU为此要制作一个体积为Nπ的M层生日蛋糕,每层都是一个圆柱体. 设从下往上数第i ...

  9. 数据排序 第三讲( 各种排序方法 结合noi题库1.10)

    说了那么多种排序方法了,下面就来先做几个题吧 06:整数奇偶排序 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 给定10个整数的序列,要求对其重新排序.排序 ...

随机推荐

  1. 设计模式学习之策略模式(Strategy,行为型模式)(13)

    转载地址:http://www.cnblogs.com/zhili/p/StragetyPattern.html 一.引言 本文要介绍的策略模式也就是对策略进行抽象,策略的意思就是方法,所以也就是对方 ...

  2. phpcms v9实现wap单页教程

    下面以添加“关于我们”这一单页为例作phpcms V9 wap手机门户添加单页的教程说明: 步骤一:复制phpcms\templates\default\wap下的maps.html,粘贴重命名为ab ...

  3. php的时间输出格式

    php中时间一般分为两种格式,一种是标准时间格式timestamp,即Y-m-d G:i:s.另一种就是时间戳. 例如: 一.标准时间与时间戳转换: //获得服务端系统时间 date_default_ ...

  4. SQLServer 维护脚本分享(06)CPU

    --CPU相关视图 SELECT * FROM sys.dm_os_sys_info SELECT * FROM sys.dm_exec_sessions SELECT * FROM sys.sysp ...

  5. Hbase原理、基本概念、基本架构

    来源:http://blog.csdn.net/woshiwanxin102213/article/details/17584043 概述 HBase是一个构建在HDFS上的分布式列存储系统:HBas ...

  6. Practical Java (一)关于reference

    Practice 1, 4, 7, 8 1. 参数传递:by value or by reference 变量型别:reference 和 primitive Java中的变量分为两种:referen ...

  7. JS获得鼠标位置

    <body> <script> function mouseMove(ev) { ev = ev || window.event; var mousePos = mouseCo ...

  8. nefu1118 最长上升子序列(LIS)

    discription:定义臻.排序数列如下:一个数列删去其中一个数后是从小到大排好序的,称这个数列为臻.排序数列.现在给你一个数列,判断它是否为臻.排序数列. intput:多组输入数据,每组有两行 ...

  9. DOM--4 响应用户操作和事件(2)

    自定义事件 //旧的方法 //创建 var event = document.createEvent('Event'); //初始化 event.initEvent('build', true, tr ...

  10. 2.2 代码块--delphi 写日志模块

    //2.2 代码块--写日志 //调用例句如:LogMsg('FTP上传线程终止',False,true); procedure LogMsg(AMsg: string; const blnIsErr ...