zoukankan      html  css  js  c++  java
  • homework-10

    既然是为了宣传...那么还是把讲解部分放在前面吧...

    借用适牛的一句话:没有人敢说自己精通动态规划。

    所以我也就着这道题稍微说说我对动态规划的理解吧...

    动态规划的基本思想就是空间换时间,就是申请更多的内存空间存储中间环节以减少重复计算。

    回到这道题,我们先看较为简单的一维问题:求数列的最大子数列。

    是不是很容易想到枚举前后端点?

    O(n^3)的时间复杂度可吃不消啊...

    于是我们就要想,如何才能存储下中间状态?

    我们可以观察到,每次枚举出两个点时,循环求区间和是一个重复计算的过程,可以在上一步的基础上加上这一步多出来的点。

    于是就要多申请一个变量空间记录这些累加和,但是时间复杂度因此下降到了O(n^2)。

    这算是最基础的动态规划思想吧...

    这道题O(n)的算法较难想,这就意味着我们要在线性时间内解决此问题。

    需要搞清楚这样一个问题:我们假定从左向右枚举点,左端点就是数列的左端点,当枚举到一个点时,子数列和为负(假定可以找到非负整数解),那是不是就意味着这一段可以直接忽略?

    我们假设从上述枚举到的右端点之后的所有点都是正数,则最大子数列必包含后面的所有点,若包含左侧的点,则数列和必小于不包含。

    如果能够理解了,那其他处理也很简单,忽略这些点,将刚才右端点的下一位置为新的左端点,重新开始枚举,这就是O(n)的算法。

    回到二维问题:求矩阵的最大子矩阵。

    有了刚才一维的基础,二维问题也就简单多了。我们需要将二维转换为一维,这就需要对矩阵做按列的累加,中间过程存入新的数组。

    我们只需用两个变量枚举此时矩阵的第i行到第j行,按列累加后生成的一维数列的最大子数列就是我们所求。

    下面用.gif动图显示二维问题的解决过程:

    谢谢观看!

    1. 用户用你的程序读入一个数组文件 (就像我们以前做过的那样),显示初始状态 (就像围棋打谱程序那样)

    1.1. 用户也可以自行定义数组的大小,或者要求随机生成一个数字矩阵。

    于是这就是两种获取数字矩阵的方式,用户可以自定义行数&列数;也可以读入一个.txt文件。

    其中,我设置了一个预处理,自动扫描目前数字矩阵的最大值,防止出现全负情况。

    2. 用户这时候有两个选择

    2.1  按 单步执行 键, 在 GUI 看到你的程序是如何一步一步算出目前最大子数组的范围,当前计算到的临时子数组是在哪里,等等。 最好用不同的颜色标识不同的状态。

    2.2  按 自动运行 键, 在 GUI 看到程序自动运行,并自动显示过程, 每次改变状态的时候要稍作停留 (例如 1 秒钟的时间)

    黄色底色代表目前扫描到的子矩阵,数字红色表示最大结果所在的子矩阵,旁边的maximum表示最大值。

    可以点击"前进一步"或"自动进行"。

    3. 咳,我没看清楚!  这时最好有一个 倒带 / 回滚 的键, 让用户可以看清楚关键的几步。

    (当然,用户可以选择是普通模式还是扩展定义的连通模式)

    可以点击"后退一步"。

    抱歉括号里的内容没看到...写博客时候才注意...也就没做v和h...不过也并没有技术含量...

    于是随手测了一组数据...目测是正确的...

    代码请见GitHub

  • 相关阅读:
    Spring IoC详解
    Hibernate 和Mybatis的区别
    Nand Flash 驱动框架
    Nor Flash 驱动框架
    USB驱动框架
    输入子系统框架
    module_init 内核调用过程
    平台设备驱动框架
    LCD驱动框架
    嵌入式-开篇
  • 原文地址:https://www.cnblogs.com/yimingzou/p/3464534.html
Copyright © 2011-2022 走看看