• PHP 求n*m二维矩阵最大子矩阵 O(n*n*m)


     1 <?php
     2  #求二维矩阵的最大子矩阵
     3  
     4  #构造求和表
     5  #s[i][j]表示从1..i行,1..j列所有元素之和
     6  #可以利用公式s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1]s[j - 1] + a[i][j]求得
     7  function build_sum_tab($a) {
     8      #初始化第0列和
     9      for ($i = 0; $i < count($a); $i++) {
    10          $s[$i][0] = 0;
    11          for ($j = 0; $j <= $i; $j++) {
    12              $s[$i][0] += $a[$j][0];
    13          }
    14      }
    15  
    16      #初始化第0行和
    17      for ($i = 0; $i < count($a[0]); $i++) {
    18          $s[0][$i] = 0;
    19          for ($j = 0; $j <= $i; $j++) {
    20              $s[0][$i] += $a[0][$j];
    21          }
    22      }
    23  
    24      for ($i = 1; $i < count($a); $i++) {
    25          for ($j = 1; $j < count($a[0]); $j++) {
    26              $s[$i][$j] = $s[$i - 1][$j] + $s[$i][$j - 1] - $s[$i - 1][$j - 1] + $a[$i][$j];
    27          }
    28      }
    29  
    30      return $s;
    31  }
    32  
    33  #计算最大子矩阵
    34  function max_sub_matrix($a, $s) {
    35      $rows = count($a);
    36      $cols = count($a[0]);
    37      #限定行的上下界
    38      $max_sum = 0;
    39      for ($low = 0; $low < $rows; $low++) {
    40          for ($high = $rows - 1; $high >= $low; $high--) {
    41              #将确定上下界的行进行线性查找
    42              #利用求和数组算出单列的和值,将这个上下界行矩阵看成一维矩阵求连续最大子序列和
    43              #单列和值利用公式 sc = s[high][col] - s[low - 1][col] - s[high][col - 1] + s[low - 1][col - 1] 求得
    44              $sum = $s[$high][0] - (isset($s[$low - 1][0]) ? $s[$low - 1][0] : 0);
    45              $max_sum = max($max_sum, $sum);
    46              for ($col = 1; $col < $cols; $col++) {
    47                  $sum_col = $s[$high][$col] - $s[$high][$col - 1] - (isset($s[$low - 1][$col]) ? $s[$low - 1][$col] : 0) + (isset($s[$low - 1][$col]) ? $s[$low - 1][$col - 1] : 0);
    48                  // echo "low: {$low} high: {$high} sum: {$sum} max: {$max_sum} sum_col: {$sum_col}<br>";
    49                  $sum = max($sum_col, $sum + $sum_col);
    50                  $max_sum = max($max_sum, $sum);
    51              }
    52          }
    53      }
    54  
    55      return $max_sum;
    56  }
    57  
    58  #随机二维数组生成器
    59  function build_matrix($n, $m) {
    60      $a = array();
    61      for ($i = 0; $i < $n; $i++) {
    62          for ($j = 0; $j < $m; $j++) {
    63              $a[$i][$j] = rand(-9, 9);
    64          }
    65      }
    66  
    67      return $a;
    68  }
    69  
    70  $a = build_matrix(2, 2);
    71  $s = build_sum_tab($a);
    72  $max = max_sub_matrix($a, $s);
    73  print_r($a);
    74  echo "<br>";
    75  print_r($s);
    76  echo "<br>";
    77  print_r($max);
    78  ?>
  • 相关阅读:
    Java中的异常处理
    Java源码阅读Vector
    Java源码中遇到的一些问题(更新中)
    Java迭代器原理
    有趣的位运算-与或非
    有趣的位运算-移位运算
    为何要使用原码, 反码和补码?
    有趣的位运算-异或
    为什么实现Serializbale接口就能够进行序列化?
    死锁,活锁,饥饿
  • 原文地址:https://www.cnblogs.com/zemliu/p/2484420.html
Copyright © 2020-2023  润新知