http://acm.pku.edu.cn/JudgeOnline/problem?id=1050
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 21973 | Accepted: 11400 |
Description
Input
Output
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比较,最后输出的一定是最大矩阵和。
除了按照程序中按初始位置和结束位置枚举外,还可以枚举每一列中的元素个数和起始位置写循环。