poj1050--最大子序列和

http://acm.pku.edu.cn/JudgeOnline/problem?id=1050

                                                                                              To the Max
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 21973 Accepted: 11400

Description

Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle.
As an example, the maximal sub-rectangle of the array:

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
is in the lower left corner:
9 2
-4 1
-1 8
and has a sum of 15.

Input

The input consists of an N * N array of integers. The input begins with a single positive integer N on a line by itself, indicating the size of the square two-dimensional array. This is followed by N^2 integers separated by whitespace (spaces and newlines). These are the N^2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in the second row, left to right, etc. N may be as large as 100. The numbers in the array will be in the range [-127,127].

Output

Output the sum of the maximal sub-rectangle.

Sample Input

40 -2 -7 0 9 2 -6 2-4 1 -4  1 -18  0 -2

Sample Output

15

与hdu1003不同的题,但却是与1003相同的思想,具体代码如下:

代码
   
     
1 #include < stdio.h >
2 #include < stdlib.h >
3 #include < string .h >
4   int n,a[ 101 ][ 101 ];
5   int s[ 101 ];
6 int ma( int * p){ ————最大子序列的和,并返回最大值
7 int i,max =- ( 1 << 30 ),b;
8 b = p[ 1 ];
9 for (i = 2 ;i <= n;i ++ )
10 {
11 if (b < 0 )b = p[i];
12 else b = b + p[i];
13 if (max < b)max = b;
14 }
15 return max;
16 }
17
18 int main(){
19 int i,j,l,k,max =- ( 1 << 30 ),t;
20 scanf( " %d " , & n);
21 for (i = 1 ;i <= n;i ++ )
22 for (j = 1 ;j <= n;j ++ )
23 scanf( " %d " , & a[i][j]);
24 memset(s, 0 , sizeof (s));
25 for (l = 1 ;l <= n;l ++ ) —————代表结束行
26 for (i = 1 ;i <= n;i ++ )——————代表起始行
27 { for (j = i;j <= l;j ++ )
28 for (k = 1 ;k <= n;k ++ )
29 s[k] += a[j][k];——————s[k]中存第k列从i到l的所有数的和
30 t = ma(s);
31 if (max < t)max = t;
32 memset(s, 0 , sizeof (s));
33 }
34 printf( " %d\n " ,max);
35 return 0 ;
36 }

经验总结:编程过程中,注意运用化未知为已知的数学思维。 

本题虽然为矩阵,但思想就是将它转化为一列数,然后再求最大子序列和。但如何转化?

7 -8 9

-4 5 6

1 2 -3

主要是将同一列中的若干数合并。比如,从第一行开始,到第2行结束,每一列的和组成的序列为:

3 -3 15

然后求此序列的最大子序列和。求出后与max比较,最后输出的一定是最大矩阵和。

除了按照程序中按初始位置和结束位置枚举外,还可以枚举每一列中的元素个数和起始位置写循环。

 

你可能感兴趣的:(poj)