計蒜客:最大子陣
阿新 • • 發佈:2019-01-14
問題:
給定一個
的矩陣
,求
中的一個非空子矩陣,使這個子矩陣中的元素和最大。
其中,
的子矩陣指在
中行和列均連續的一部分。
輸入格式:
輸入的第一行包含兩個整數 ,分別表示矩陣 的行數和列數。
接下來 行,每行 個整數,表示矩陣 。
輸出格式:
輸出一行,包含一個整數,表示
中最大子矩陣的元素和。
樣例輸入:
3 3
2 -4 1
-1 2 1
4 -2 2
樣例輸出:
6
題解:
思路:第一映像是暴力列舉,不過顯然會超時,然後就想到了DP(動態規劃)。其實因為矩陣肯定是對齊的,所以如我們將兩行加起來求最大子陣列就可以得到一個行數為2的子矩陣。所以問題就轉化成了求一個數組的最大子陣列和。然後就是列舉第i行到第j行相加得到的陣列了。注意res的值不能設為0,因為可能最後的結果是負數。
知識點:
子矩陣:
是在矩陣選取部分行、列所組成的新矩陣。
例如:
它亦可用A(3;2)表示,顯示除掉第3行和第2列的餘下的矩陣。這兩種方法比較常用,但還是沒有標準的方法表示子矩陣。
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int N, M;
int a[105][105];
int dp[105];
int getMax(int a[], int M)
{
int max = a[0], temp = 0;
for (int i = 0; i < M; i++)
{
if (temp > 0)
temp += a[i];
else
temp = a[i];
max = max > temp ? max : temp;
}
return max;
}
int main(void)
{
cout << "請輸入矩陣的行和列:";
cin >> N >> M;
cout << "請輸入矩陣的資料:" << endl;
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < M; ++j)
{
cin >> a[i][j];
}
}
int Max = a[0][0], temp;
for (int i = 0; i < N; i++)
{
memset(dp, 0, sizeof(dp));
for (int j = i; j < N; j++)
{
for (int k = 0; k < M; k++)
{
dp[k] += a[j][k];
}
temp = getMax(dp, M);
Max = Max > temp ? Max : temp;
}
}
cout << "最大值為:" << Max << endl;
system("pause");
return 0;
}