题意
给你一个n*n的方正,每一个格子都一个值,问它的子矩阵的sum最大为多少
思路
其实就是枚举完上下边界之后转化成了一维求最大子段,而枚举最大子段可以使用dp优化。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
int a[105][105];
int prefix[105][105];
int sum[105][105];
int dp[105];
int main(){
int n, ans = -128;
scanf("%d", &n);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
scanf("%d", &a[i][j]);
ans = max(ans, a[i][j]);
prefix[i][j] = prefix[i][j - 1] + a[i][j];
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
sum[i][j] = sum[i - 1][j] + prefix[i][j];
}
}
for(int i = 1; i <= n; i++){
for(int j = i; j <= n; j++){
memset(dp, 0, sizeof(dp));
for(int k = 1; k <= n; k++){
dp[k] = dp[k - 1] + sum[j][k] - sum[i - 1][k] - (sum[j][k - 1] - sum[i - 1][k - 1]);
ans = max(ans, dp[k]);
if(dp[k] < 0) dp[k] = 0;
}
}
}
printf("%d\n", ans);
return 0;
}