homework01

首先考虑一维的情况。我们可以把问题转化为:
for(i=0;i<MAX;i++)以a[i]结束的最大子数组和。
而以a[i]结束的最大子数组和必须包含他自己,那么他包不包含前面的数呢?
这就看前面对构成一个比他大的子数组和有没有贡献,即前面的数组和是不是大于0.
这样我们从a[0]开始,每次得到的结果就都会被下一次用到。这样只需要O(N)就可以找出最大的子数组和。
而清楚了一维之后,二维只需要枚举上下边界即可。
 1 #include<stdio.h>
 2 #include<string.h>
 3 int FindMax(int a[],int n)
 4 {
 5     int b[100],wtf=-1<<30;
 6     int i;
 7     for(i=0;i<n;i++)
 8         b[i]=a[i];
 9     for(i=1;i<n;i++)
10     {
11         if(b[i-1]>0)
12             b[i]+=b[i-1];
13         if(wtf<b[i])
14             wtf=b[i];
15     }
16     return wtf;
17 }
18 int main()
19 {
20     int n;
21     scanf("%d",&n);
22     int a[100][100];
23     memset(a,0,sizeof(a));
24     int i,j;
25     for(i=0;i<n;i++)
26         for(j=0;j<n;j++)
27             scanf("%d",&a[i][j]);
28     int up,down;
29     int temp[100],record,final=-1<<30;
30     for(up=0;up<n;up++)
31     {
32         memset(temp,0,sizeof(temp));
33         for(down=up;down<n;down++)
34         {
35             for(j=0;j<n;j++)
36                 temp[j]+=a[down][j];
37             record=FindMax(temp,n);
38             if(record>final)
39                 final=record;
40         }
41     }
42     printf("%d\n",final);    
43     return 0;
44 }


这个题是POJ的1050题。。我就不测试了。

 
posted @ 2013-09-20 01:29  猪小乐  阅读(154)  评论(1)    收藏  举报