zoukankan      html  css  js  c++  java
  • 最大子矩阵和

    参考来源:

    https://blog.csdn.net/fengyingjie2/article/details/54427146

    https://blog.csdn.net/kavu1/article/details/50547401

    题目:

    给定一个矩阵,都是整数,其中(n≤500),求出其中的最大子矩阵

    解题思路:

    O(n^2*n^2*n^2)的做法:

    很容易想到,可以枚举一个矩阵的左上角和右下角的坐标确定这个矩阵,然后,再用两个循环进行统计

    O(n^2*n^2)的做法:

    对于上面的方法,提前处理一个前缀和,即可省去后面统计的时间复杂度。

    正解,即O(n³)事实上并没有这么多

    想要做对这道题,我们先要明白一个最大子段和算法的做法:

    例如数字a={8,-2,3,-11,5},我们需要求出一段连续数字的最大和是什么

    我们的思想是DP

    设f[i]表示从1~i这些位置中的最大子段和

    如何转移?对于当前的点i,我们只有两种状态,选择与上一个子段和连接或者自己重新构成一个子段和。

    若选,则与1~i-1的最大子段和有关系,即1~i-1的最长子段和加上当前的a[i],重新构成一个子段和

    若不选,则与1~i-1最大子段和没有关系,自己重新构成了一个子段和

    两者取较大者,即可解决

    列出状态转移方程:f[i]:=max(a[i],f[i-1]+a[i])

    时间复杂度 O(n)


    说了这么多都是铺垫,下面是重点:

    为了能够在原始矩阵里很快得到从 i 行到 j 行 的上下值之和,我们这里用到了一个辅助矩阵,它是原始矩阵从上到下加下来的。
    假设原始矩阵是matrix, 它每一层上下相加后得到的矩阵是total,那么我们可以通过如下代码实现:

    int[][] total = matrix;    
    for (int i = 1; i < matrix[0].length; i++) {    
        for (int j = 0; j < matrix.length; j++) {    
        total[i][j] += total[i-1][j];    
        }    
    }    

    如果我们要求第 i 行到第 j 行之间上下值的和,我们可以通过total[j][k] - total[i-1][k] 得到, k 的范围从1 到 matrix[0].length - 1。
    有了这些知识点,我们只需要在所有的情况下,把它们所对应的局部最大子矩阵进行比较,就可以得到全局最大的子矩阵。代码如下:

     1 public int subMaxMatrix(int[][] matrix) {    
     2             
     3         int[][] total = matrix;    
     4         for (int i = 1; i < matrix[0].length; i++) {    
     5             for (int j = 0; j < matrix.length; j++) {    
     6                 total[i][j] += total[i-1][j];    
     7             }    
     8         }    
     9             
    10         int maximum = Integer.MIN_VALUE;    
    11         for (int i = 0; i < matrix.length; i++) {    
    12             for (int j = i; j < matrix.length; j++) {    
    13                 //result 保存的是从 i 行 到第 j 行 所对应的矩阵上下值的和    
    14                                 int[] result = new int[matrix[0].length];    
    15                 for (int f = 0; f < matrix[0].length; f++) {    
    16                     if (i == 0) {    
    17                         result[f] = total[j][f];    
    18                     } else {    
    19                         result[f] = total[j][f] - total[i - 1][f];    
    20                     }    
    21                 }    
    22                 int maximal = maxSubsequence(result);    
    23                     
    24                 if (maximal > maximum) {    
    25                     maximum = maximal;    
    26                 }    
    27             }    
    28         }    
    29             
    30         return maximum;    
    31     }   
  • 相关阅读:
    JTAG各类接口针脚定义及含义
    【转载】关于quartus ii软件中注释乱码问题的解决方法
    【转载】浅谈阻塞和非阻塞语句的本质区别
    labview事件结构学习
    Labview按钮的机械动作
    LabVIEW中数组的自动索引
    opencv实例三:播放AVI格式视频
    TensorRT 不支持Tensorflow的操作有如下
    深度学习模型stacking模型融合python代码,看了你就会使
    sklearn的K折交叉验证函数KFold使用
  • 原文地址:https://www.cnblogs.com/huashanqingzhu/p/8684624.html
Copyright © 2011-2022 走看看