TimusOJ - 1146. Maximum Sum(子矩陣的最大累加和)
阿新 • • 發佈:2019-01-07
TimusOJ - 1146. Maximum Sum(子矩陣的最大累加和)
題目連結
題目
解析
首先,解這道題之前,先要知道求一維的最大子陣列和LeetCode53和Hdu1003。
解析:
假設一個2
行4
列的矩陣如下:
-2 3 -5 7
1 4 -1 -3
如何求必須含有2
行元素的子矩陣的最大累加和? 做法是將兩列的元素累加,然後得到累加陣列[-1, 7, -6, 4]
,然後通過求一維陣列的最大累加和的方法求出這個累加陣列的最大累加和,結果是7
。也就是說,必須含有2
行元素的子矩陣中的最大和為7
,且這個子矩陣是:
3
4
也就是說: 如果一個矩陣一共有n
n
行元素的情況下,我們只要把矩陣中的每一列的n
個元素累加生成一個累加陣列,然後求出這個累加陣列的最大累加和,這個最大累加和就是必須含有k
行元素的子矩陣中的最大累加和。(類似壓縮的思想)
明白了上述的過程,然後就是按照上述過程求出所有的 "上下組合"的解的最大值即可。具體過程看下面:
- 注意: 每次
cols
陣列的求取,是利用上次求出的結果加上這次的,這樣可以將時間複雜度從O(N^4)
降低到O(N^3)
;
import java.io.BufferedInputStream;
import java.util.Scanner;
public class Main {
/** O(N^3) **/
public static void main(String[] args){
Scanner cin = new Scanner(new BufferedInputStream(System.in));
int n = cin.nextInt();
int[][] matrix = new int[n][n];
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
matrix[ i][j] = cin.nextInt();
}
}
// more usual solution not just square matrix (n != m)
n = matrix.length;
int m = matrix[0].length;
int res = Integer.MIN_VALUE;
for(int i = 0; i < n; i++){
int[] cols = new int[m]; // cols
for(int j = i; j < n; j++){
for(int k = 0; k < m; k++) {
cols[k] = cols[k] + matrix[j][k];
}
int preMax = cols[0];
int maxx = cols[0];
for(int k = 1; k < m; k++){
preMax = preMax > 0 ? preMax + cols[k] : cols[k];
maxx = Math.max(preMax, maxx);
}
res = Math.max(res, maxx);
}
}
System.out.println(res);
}
}