POJ-1050 动态规划 子矩阵最大值,二位转一维处理
详见代码:
#include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #define MAXN 100 using namespace std; // 给定一个有数值的矩形,求出和最大的子矩形 // 经典的DP问题 /* 思路:枚举所有的行,然后将这些行的列进行相加构成一个串 然后再进行一次一维空间上的DP即可 */ int N, M[MAXN+5][MAXN+5], sum[MAXN+5][MAXN+5], seq[MAXN+5]; int DP() { int Max = 0x7fffffff+1; for (int j = 1; j <= N; ++j) { for (int i = 1; i <= N; ++i) { sum[i][j] = sum[i-1][j] + M[i][j]; // sum[i][j] 表示1-i行上j列元素的和 } } for (int i = 1; i <= N; ++i) { // 枚举所有的行区间 for (int j = i; j <= N; ++j) { for (int k = 1; k <= N; ++k) { seq[k] = sum[j][k] - sum[i-1][k]; // 计算出[i,j]行之间k列的和值 } for (int k = 1; k <= N; ++k) { seq[k] = seq[k-1] + seq[k] > 0 ? seq[k-1] + seq[k] : 0; Max = max(Max, seq[k]); } } } return Max; } int main() { while (scanf("%d", &N) == 1) { for (int i = 1; i <= N; ++i) { for (int j = 1; j <= N; ++j) { scanf("%d", &M[i][j]); } } printf("%d\n", DP()); } return 0; }