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 ?>