給一個N*N的int矩陣,求出全部子矩陣中的最大和。ios
枚舉全部左上角起點(startRow,startCow)O(N^2)和右下角終點(endRow, endCow)O(N^2),求出子矩陣的和O(N^2)。複雜度O(N^2)* O(N^2)* O(N^2)= O(N^6)。c++
動態規劃。算法
memo[i][j] = memo[i - 1][j] + memo[i][j - 1] - memo[i - 1][j - 1] + data[i][j]數組
其中memo[i][j]表示(0,0)到(i,j)之間的和,data[i][j]表示第i行j列的數字。spa
複雜度O(N^2)* O(N^2)= O(N^4)。code
#include <iostream> #include <algorithm> using namespace std; #define INT_MIN (-2147483647 - 1) int main() { int N, memo[101][101], ms = INT_MIN; cin >> N; for (int i = 0; i <= N; i++) memo[i][0] = memo[0][i] = 0; for (int i = 1; i <= N; i++) for (int j = 1; j <= N; j++) { int t; cin >> t; memo[i][j] = memo[i - 1][j] + memo[i][j - 1] - memo[i - 1][j - 1] + t; } for (int sr = 1; sr <= N; sr++) for (int sc = 1; sc <= N; sc++) for (int er = sr; er <= N; er++) for (int ec = sc; ec <= N; ec++) ms = max(ms, memo[er][ec] - memo[sr - 1][ec] - memo[er][sc - 1] + memo[sr - 1][sc - 1]); cout << ms << endl; return 0; }
仍是動態規劃,只不過將二維降到一維求解。 ci
枚舉全部起點的行和終點的行O(N^2) ,一維數組squashed[]記錄起點行和終點行之間的各列之和,it
squashed[c] += memo[er][c]io
以後對squashed數組這個一維空間上計算,至關於枚舉了起點的列和終點的列,但因爲是一維空間,所以複雜度O(N)。class
總體複雜度O(N^2) * O(N) = O(N^3)。
#include <iostream> #include <algorithm> using namespace std; #define INT_MIN (-2147483647 - 1) int main() { int N, memo[100][100], ms = INT_MIN; cin >> N; for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> memo[i][j]; for (int sr = 0; sr < N; sr++) { int squashed[100] = {0}; for (int er = sr, sum = INT_MIN; er < N; er++) { for (int c = 0; c < N; c++) squashed[c] += memo[er][c]; for (int c = 0, candidate = 0; c < N; c++) { candidate += squashed[c]; sum = max(sum, candidate); candidate = max(0, candidate); } ms = max(ms, sum); } } cout << ms << endl; return 0; }