ZOJ1074 最大子矩阵的和
题目意思很简单了,输入一个行数和列数相同的矩阵a[n][n]然后求最大的子矩阵和。它实际上就是最大子段和的二维推广,
可以按照一维的思路来做。首先将每一列的和压缩成一个b[j]数组的元素,它代表a[i1][j]+a[i1+1][j]+......+a[i2][j]的和,
这是保持列数不变再把它压缩成一个元素,这样进行压缩后实际上就是求b[1].....b[j]..b[n]的最大子段和,这就转化为一维的情况。
View Code
1 #include<stdio.h>
2 #include<stdlib.h>
3
4 #define N 101
5 int a[N][N];
6 int b[N];
7
8 int MaxSum(int n)//求一维情况下的最大子段和为
9 {
10 int a = 0,sum = 0,i;
11 for(i=0; i<n; i++)
12 {
13 if(a > 0)
14 a += b[i];
15 else
16 a = b[i];
17 if( a > sum )
18 sum = a;
19 }
20 return sum;
21 }
22
23 int MaxSum2(int n)//将二维的压缩成一维
24 {
25 int sum=0,i,j,k,max;
26 for(i=0; i<n; i++)//这里要枚举了,从第一行开始一行一行
27 找最大的b[j]
28 {
29 for(k=0; k<n; k++) b[k] = 0;
30 for(j=i; j<n; j++)
31 {
32 for(k=0; k<n; k++)
33 {
34 b[k] += a[j][k];//进行压缩。
35 }
36 max = MaxSum(n);
37 if(max > sum)
38 sum = max;
39 }
40 }
41 return sum;
42 }
43
44 int main()
45 {
46 int i, ncases, j,num;
47
48 scanf("%d",&ncases);
49 for(i=0; i<ncases; i++)
50 {
51 for(j=0; j<ncases; j++)
52 {
53 scanf("%d",&a[i][j]);
54 }
55 }
56 num = MaxSum2(ncases);
57 printf("%d\n",num);
58 // system("pause");
59 return 0;
60 }
61