題目
給定一個 M*N 的矩陣MATRIX,要求在此矩陣中尋找一個非空子矩陣,並使得該矩陣的和最大。
輸入
要求首先輸入兩個整數 M 和 N,分別表示矩陣的行和列,再在接下來依次輸入矩陣的值MATRIX[I][J]
樣例:
3 3 2 -4 1 -1 2 1 4 -2 2
輸出
輸出一行,包含一個整數,表示 MATRIX中最大子矩陣的元素和
樣例:
6
分析
當看到這道題時,腦子裏首先是怎麼尋找子矩陣,並且要把所有的子矩陣都找一遍。到這裏想了想以前學過的線性代數,似乎沒想起什麼辦法尋找子矩陣。對於一個矩陣來說,其子矩陣實在太多了,我們需要找到一個合適的辦法來挨個找它的子矩陣。那麼我們怎麼找,還是這個問題,規律在哪?因此我們需要自己在本子或者其他地方做一些草稿,在這個過程中,我們會發現矩陣他有一個特點:它的形狀是一個矩形(這不廢話嗎)...但是對於矩形,我們可是知道的,我們只要通過一組對角的座標就能確定這個矩形的位置。因此拿到矩陣裏來也是一樣的,我們只要兩個座標點就能確定一個子矩陣。那麼這就很好辦了。我們只需要挨着把所有座標點都訪問一遍就行了。
package 計蒜客;
import java.util.Scanner;
public class Matrix {
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int row=sc.nextInt();
int colum=sc.nextInt();
int[][] matrix=new int[row][colum];
/*
* 輸入矩陣的值
*/
for(int i=0;i<row;i++)
{
for(int j=0;j<colum;j++)
{
matrix[i][j]=sc.nextInt();
}
}
/*
* 定義變量valueTMP用來就算矩陣元素和,
valueMAX用來保存最大值
*/
int valueTMP=0;
int valueMAX=matrix[0][0];
/*
* 六層循環,第一二層確定矩陣的第一個座標
* 第三四層確定矩陣的第二個座標
* 第五六層把兩個座標點確定的矩陣的元素求和,其實也就是遍歷了一遍
* */
for(int a=0;a<row;a++)
{
for(int b=0;b<colum;b++)
{
for(int a1=a;a1<row;a1++)
{
for(int b1=b;b1<colum;b1++)
{
// System.out.print("start:"+a+","+b+"^^^^^^");
// System.out.println("end:"+a1+","+b1);
for(int r=a;r<=a1;r++)
{
for(int c=b;c<=b1;c++)
{
valueTMP+=matrix[r][c];
}
}
if(valueTMP>valueMAX)
{
valueMAX=valueTMP;
}
//每次用完之後,都要把valueTMP置0
valueTMP=0;
}
}
}
}
System.out.println(valueMAX);
}
}
。這裏有幾個細節需要看一下,第一個就是valueMAX的初始值問題,賦值爲矩陣第一個元素,而不是0,考慮一種極端情況,若所有元素都爲負數,0的話將會輸出錯誤結果。第二,循環的三四層,也就是確定另一個座標,我們要從上一個座標開始,而不是上一個座標的下一個開始,這裏我們考慮另一種極限情況,子矩陣只有一個元素。第三,也就是valueTMP,已經在註釋中說到了。
最後,運行結果:
如果將註釋的兩個輸出語句取消註釋,將會得到所有情況子矩陣的信息,如下:
筆者能想到的解決方法暫時就是這一種,希望大家多多指教,如有問題,請評論區留言!歡迎轉載收藏!