POJ 1050 / HDU 1081 To the Max(最大子矩陣和)
阿新 • • 發佈:2018-12-24
題目連結:
題意:給出一個n*n的矩陣,正負均有。求一個子矩陣使得該子矩陣的和儘可能的大。
思路:類似於最大子段和,即將前i行至前j行的矩陣壓縮成一行,利用一個數組c,c[k]表示第k列從第i行到第j行的和,接下來只需對陣列c求最大子段和,結果即為第i行到第j行中的最大子矩陣和。
程式碼:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int N = 5e2 + 10; const int INF = 0x3f3f3f3f; long long a[N][N]; long long c[N]; int n, m; long long getAns() { long long ans = 0; for (int i = 1; i <= n; i++) { for (int j = i; j <= n; j++) { long long res = 0; for (int k = 1; k <= m; k++) { c[k] = (i == j ? a[i][k] : c[k] + a[j][k]); if (res < 0) res = c[k]; else res = res + c[k]; ans = max(res, ans); } } } return ans; } int main() { while (scanf("%d%d", &m, &n) != EOF) { long long _max = -INF; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%lld", &a[i][j]); _max = max(_max, a[i][j]); } } // 若矩陣全為負數,則認為結果為0 long long ans = (_max < 0LL ? 0 : getAns()); printf("%lld\n", ans); } return 0; }