总时间限制: 1000ms
- 内存限制: 65536kB
- 描述
- 已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
的最大子矩阵是
9 2
-4 1
-1 8
这个子矩阵的大小是15。 - 输入
- 输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[-127, 127]。
- 输出
- 输出最大子矩阵的大小。
- 样例输入
-
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2 - 样例输出
-
15
- 来源
- 翻译自 Greater New York 2001 的试题
- 牛逼的算法我也想不出来,只好暴力DP了
1 #include<bits/stdc++.h> 2 using namespace std; 3 int N; 4 int a[300][300]; 5 int sum[300][300]; 6 int dp[300]; 7 int ANS; 8 int main(){ 9 scanf("%d",&N); 10 for(int i=1;i<=N;i++){ 11 for(int j=1;j<=N;j++){ 12 scanf("%d",&a[i][j]); 13 } 14 } 15 for(int j=1;j<=N;j++){ 16 for(int i=1;i<=N;i++){ 17 sum[j][i]=sum[j][i-1]+a[i][j]; 18 } 19 } 20 for(int i=1;i<=N;i++){//矩阵的上界 21 for(int j=i;j<=N;j++){//矩阵的下界 22 memset(dp,0,sizeof(dp)); 23 for(int k=1;k<=N;k++){ 24 int delta=sum[k][j]-sum[k][i-1]; 25 if(dp[k-1]<=0){ 26 dp[k]=delta; 27 } 28 else dp[k]=dp[k-1]+delta; 29 } 30 for(int g=1;g<=N;g++){ 31 ANS=max(ANS,dp[g]); 32 } 33 } 34 } 35 cout<<ANS; 36 return 0; 37 }