homework-02 最大子区域和
题目描述
题目建立上一个作业的题目基础上,上一次作业是要求在一个一维序列里找一个最大连续子串,这次task最基础的要求是在一个二维表里找一个最大连续子矩形,但是这次作业有若干个升级版,分别要求可以加入运行参数[\h][\v][\a],其中\h选项代表给定的二维表是水平循环的,\v代表给定的二维表是水平循环的,\a表示结果可以突破矩形的限制,寻找一个最大的连通块,而非矩形。
我的思路
这次题目最难的一部分是实现/a的操作,相比之下其他要求实现比较简单,先从简单的说起。
从二维表里找一个最大的子矩形,这和一维的情况非常类似,这促使我们思考如何将这种情况转化到一维的情况,我们观察二维表中的任意一个子矩形。

我们可以发现子矩形只是选中了一些连续的子列,每个子列的始终位置都是相同的,而且每个子列的值都不会影响其他子列的值,这样我们把子列的值得的和作为一个元素,就得到了一个一维序列。

这时就可以使用在作业毅力的算法来处理这种状态,考虑到要遍历到所有情况,我们仅需要枚举行上每个行之间的区间,时间复杂度为O(n^2),然后再用homework-01里方法处理两行之间的数据即可,时间复杂度为O(m),总时间复杂度为O(n^2m),这样这道题目就比较好的解决了。不过我们并不能确定这个问题时间复杂度下界就是O(n^2m),找出一个O(nm)的算法还是非常有吸引力的,毕竟这和一维的情况存在更多的一致性。
有了上面的基础我们再考虑/v和/h的情况,这两种情况实际上是等价的,因此我们仅考虑/h的情况,/h选项表示二维表在水平方向上时循环连通的,我采用了在水平方向上扩展一次二维表的方法,扩展如下图

扩展之后我们在n*m的矩阵的基础上得到了一个n*2m的矩阵上进行同样的算法,这时还需要加一个限制,考察一行发现如果覆盖整个一行的列长超过m的话会在当前解中加入重复的元素,我们此时枚举列的起始位置,同时保证列长为m即可,这样的时间复杂度为O(n^2m^2),还是一个非常理想的时间复杂度。
最后我们来讨论一下/a选项,它要求找一个任意的最大联通块即可,这个问题难度很高(因为我想了好几天都没想到一个好的解法),题目要求的矩阵最大规模为32*32,初看这个规模显得非常小,但是对于这道题目我们难以找到一个多项式的解,今天在课上也确认了这确实是一个NP问题,解决这个问题有很多思路,这里我们简单讨论几种思路,从经验上我们可以发现如果一个非负的格子在最终解里,那么它相邻的非负格子也一定在最终解里,这样考虑的话就把我们生成矩阵中的所有非负连通块,最终解一定是某些块的集合加入它们之间相连的负的格子,我们枚举这样的集合,然后判断集合里的块是否能相连,具体方法为从一个块中向外遍历负格子,如果遍历的路径和的绝对值已经比该块大了,就停止遍历,可以使用记忆化来优化一下,如果能遍历的目标块就找一条最小的(同时要看这条路的绝对值和是否也比目标块小),这时把这两块连成一块,继续连接其他块,考虑每一种情况后取一个最优值,视为找到的一个解,这个方案的优点是能较快的找到一个好的近似解,缺点是代码复杂,难以实现,而且它目前仅能求一个近似解,并不能证明它是最优的,不满足题目要求。再考虑另一种方法,状态压缩动态规划,状压DP将每一行压为一个状态,这个状态用一个r进制数表示,由于本题要求找到的块具有连通性,那么我们需要一个m进制的数来维护连通性,但本题目有一定特殊性,如果把它视作插头Dp的话这是一个4插头DP也就是说如果相邻两个格子都被选中的话那么他们一定联通的(感谢Tony Shaw的指导),这样考虑的话仅需m/2进制就可以满足需求,我们仅需维护我们当前状态里没有不与当前行连通的块,并且用每一个只有一个块的状态去更新最终解,这样就能很好地解决问题。这个方案的优点是思路清晰,代码相对好写(实际上实现也相当困难),确定是时间复杂度高,我们假定矩阵的规模满足m < n,那么我们的复杂度为O(n(m/2)^(2m)),利用轮廓线优化可以得到O(nm(m/2)^m)的复杂度,题目限制是(n,m)<=(32,32),最坏情况下该算法的规模为32*32*16^32,这个复杂度实在难以接受,但是如果我们考虑一种特例——矩阵的一个维度特别小,那么这种方法就有很大的优势。
一些收获
经过一晚上的奋斗成功在VS2012下完成了performance analyze 和 unit test,第一次做这个非常吃力,但是还是颇有收获,先看看unit test。

写了三个测试方法,分别测试了三个选项以及基础情况的输出,使用了三个不同的测试样例,这次为了能更快进行一些初步的unit test实战,没有对数据进行容错处理,所以样例规模都很小,其中TestACondition我只是采用了找一个最大非负连通子块的方法来代替,所以最后的结果只是一个近似值,如果在assert宏里加入容限就能通过test。再看看测试的覆盖率。

这个工程我写了一部分函数来模块化,从上表看代码有效性还是很高的,但我初学单元测试,还不是很好的看懂覆盖图。
完成第一次单元测试后,个人感觉单元测试这个工具非常有用,但是需要很大的精力维护,它可以很好的维护代码的正确性,单元测试可能非常依赖于测试样例,管理好测试用例对于单元测试是一个重要的组成部分,编写单元测试可能还要遵循简短的方法,我在写单元测试时已经有了一个单元测试的单元测试,但我认为这样的代价是不值得的,好的单元测试应该逻辑清晰而简洁,具有非常好的可读性,以便于维护。
这次单元测试我但我耽误时间最多的是配置过程,这里有一个小细节,使用VS2012单元测试时原工程一定要导出一个DLL作为symbol才能正常连接,不过这短时间也让我熟悉了下VS中solution-projects的文件结构,感觉这个结构非常舒服,可以加入很多工具配合在一起使用同一管理,很赞一点设计。
最后看一下performance analyze

performance analyze做起来就太傻瓜化了,一键完成,不过还是学到了新工具,性能分析我使用了一个500*500的大矩阵,矩阵的元素为16位整型范围内,从上图可以看到主要的运算集中在算法模块,我在算法实现上确实牺牲一部分时间系能,程序还能采用空间换时间的方法继续优化,不过都是只是常数上的,而且会破坏代码结构,于是没有进一步优化。
homework-02 最大子区域和的更多相关文章
- 实现步骤: 推送&传感器&UIDynamic
一.本地通知基本使用: #01.请求授权(8.0以前默人授权) #02.创建本地通知 #03.设置通知内容 #04.设置通知时间(多久后发通知) #05.发送通知 二.本地通知而外设置: #01.设置 ...
- Mask RCNN 学习笔记
下面会介绍基于ResNet50的Mask RCNN网络,其中会涉及到RPN.FPN.ROIAlign以及分类.回归使用的损失函数等 介绍时所采用的MaskRCNN源码(python版本)来源于GitH ...
- plot-sin-02
draw sin 02 设置数据区域的边界线颜色 设置坐标轴的位置 code #!/usr/bin/env python # -*- coding: utf-8 -*- import numpy as ...
- 363. 矩形区域不超过 K 的最大数值和(利用前缀和转化为最大子序和问题)
题目: 链接:https://leetcode-cn.com/problems/max-sum-of-rectangle-no-larger-than-k/ 给定一个非空二维矩阵 matrix 和一个 ...
- day 02 ---class - homework
# -*- coding: utf-8 -*-# @Time : 2018/12/20 14:34# @Author : Endless-cloud# @Site : # @File : day 02 ...
- ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步
一.区域—麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念—区域(Area). 在项目上右击创建新 ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 咨询管理的架构
咨询.留言.投诉等功能是网站应具备的基本功能,可以加强管理员与用户的交流,在上次完成文章部分后,这次开始做Member区域的咨询功能(留言.投诉都是咨询).咨询跟文章非常相似,而且内容更少.更简单. ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 添加文章
上次把架构做好了,这次做添加文章.添加文章涉及附件的上传管理及富文本编辑器的使用,早添加文章时一并实现. 要点: 富文本编辑器采用KindEditor.功能很强大,国人开发,LGPL开源,自己人的好东 ...
- ASP.NET MVC5 网站开发实践(二) Member区域 - 文章管理架构
上次把member的用户部分完成,现在开始做文章管理部分.文章部分根据涉及显示现实文章列表,发布文章,修改文章,删除文章等功能.最终的实现目标是使用权限来控制用户是否能进行相应操作,管理员权限的会显示 ...
随机推荐
- QTP场景恢复之用例失败自动截图
以下代码是在QC里运行QTP来执行脚本过程,当执行过程中发现用例失败后就会自动截图,然后把用例返回到最初始的状态,模拟了场景恢复的机制 Class QCImageErrorCapture Dim qt ...
- 面试题_ Java EE 相关的面试题
为了做 Java EE 的朋友,这里列出了一些 web 开发的特定问题,你们可以用来准备 JEE 部分的面试: 10 大 Spring 框架面试题及答案(参见)10 个非常好的 XML 面试问题(Ja ...
- HDU 4902
数据太弱,直接让我小暴力一下就过了,一开始没注意到时间是15000MS,队友发现真是太给力了 #include <cstdio> #include <cstring> ],x[ ...
- Request.Querystring中文乱码问题解决
现象:近期项目中用到查询字符串传值,如果传递的是英文一切正常,但是传递中文时,使用request.querystring[]得到的是乱码. 原因:不知道为什么,可能是编码不一致问题 解决方法1:修改w ...
- Grunt + Bower—前端构建利器(转)
目前比较流行的WEB开发的趋势是前后端分离.前端采用重量级的Javascript框架,比如Angular,Ember等,后端采用restful API的Web Service服务,通过JSON格式进行 ...
- c & c++中static的总结
static 修饰的三种作用 (1) 静态局部变量 (2) 模块内的全局变量.函数,不可以被其他模块访问 (3) 类的静态成员 其中(3)只在c++中有. (1) 静态局部变量.局部变量一般在函数体内 ...
- poj 1087 A Plug for UNIX
题目描述:现在由你负责布置Internet联合组织首席执行官就职新闻发布会的会议室.由于会议室修建时被设计成容纳全世界各地的新闻记者,因此会议室提供了多种电源插座用以满足(会议室修建时期)各国不同插头 ...
- <三>面向对象分析之UML核心元素之参与者
一:版型 --->在UML里有一个概念叫版型.有些书里也称类型,构造型. --->这个概念是对一个UML元素基础定义的扩展.在同一个元素基础定义的基础上赋予特别 ...
- 【原】cocos2d-x 2.0.4 不支持https协议 CURLE_UNSUPPORTED_PROTOCOL
我们项目组用的cocos2d-x版本还比较老,各种好的功能不能用. 今天就让我遇到一个问题,使用CCHttpClient发送http请求的时候,https协议的不支持,返回失败信息如下 errorco ...
- HDU 5883 The Best Path
The Best Path Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tot ...