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比较,最后输出的一定是最大矩阵和。

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

 

posted @ 2010-07-23 21:41  Danty  阅读(1466)  评论(0编辑  收藏  举报