【现代程序设计】【Homework-01】

1维的最大子数组之和

对于1维的最大子数组之和

假设f[i]表示:对于1..i这个序列中,包含i这个元素的最大序列的值

则对于f[i],0<i<=n;

应该有

f[i]=max(a[i],f[i-1]+a[i]);

 f[1]=a[1];

 

由此一维的问题即可解决

 

时间复杂度:O(n)

空间复杂度:O(n)

2维的最大子数组之和

 

为了叙述的方便,在此我们先约定,输入的矩阵为P,行和列值分别约定为m,n

 

对于2维数组,我们虽然无法直接使用1维中的动态规划的思路

但是,如果我们可以把一整行看做一个元素

按照1维的思路,我们就可以得到一个最大的m*x的矩阵A0<x<n

 

显然A不一定是最后的答案,因为矩阵A的行值被我们限定为了m

所以我们需要枚举m,即m←1..m

 

之后要做的就很简单了

 

枚举行值等于m,列值恒定为n的所有矩阵D,并找出D中的最大子矩阵E

对于所有的EmaxE)就是最后的答案

 

 

时间复杂度=T[1维最大子数组]*T[枚举矩阵]*T[计算矩阵每一行的值]

 

前者已知为O(n)

枚举矩阵则需要一个二重的循环,即为O(n^2)

 

对于计算矩阵D中没一行的值

我们可以进行预处理

 

假设DP中的位置为:第xy

如果我们用一个数组g[i][j]表示:第i行的1..j列的元素之和为g[i][j]

则对于D中的每一行的和应该为g[i][y]-g[i][x],(0<i<=m)

每次计算的复杂度为O(1)

 

所以总的时间复杂度为:O(N^3)

 

空间复杂度:

主要用于存储P,D,E

为:O(n^2);

 

 

 

 

 

曲面2维的最大子数组之和

曲面和平面最本质的区别就是:边缘的连续问题

所以我们只需要增加3个矩阵P1P2P3,排列为:

P       P1

P2     P3

求解其中和最大的子矩阵E即可

但对于E,行列值均应分别小于m,n;

 时间空间复杂度均和2维平面最大子数组之后的复杂度相同

 

时间复杂度:O(n^3)

空间复杂度:O(n^2)

 

 

 

以下是作业所需要包含的必要的东西

开发时间:30min

效率:不知道该如何描述

心得:第一次写Blog,把自己所想的准确的表达出来,也不是想象中那么简单

 

截图:这是一个在线OJ的评测截图,因为有个题目和这个一样,所以我就偷了个懒,没有自己写测试数据  : ]

 

 

下面是二维平面最大子数组的源码,由于比较简短,我也就没有做过多的注释

如果有不明白或者觉得本人写的代码不够简洁或者有误,也欢迎各位留言

 

 

 1 #include<stdio.h>
 2 #define M 100
 3 #define max(a,b) (a)>(b)?(a):(b)
 4 
 5 
 6 
 7 /*
 8 
 9 由于比较懒,在此我先预处理了P的所有子矩阵的,每一行的值
10 
11 所以开销为O(n^3)
12 
13 但此算法的空间复杂度是可以为o(n^2)的
14 
15 但需要每次初始化一下数组的值
16 
17 所以我就比较懒的开了个O(n^3)的复杂度  : ]
18 
19 */
20 
21 int f[M][M][M],g[M][M][M],a[M][M],i,j,k,l,n,m;
22 
23 main()
24 {
25     //输入
26     scanf("%d%d",&m,&n);
27     for(i=0;i<m;i++)
28     for(j=0;j<n;j++)
29         scanf("%d",a[i]+j);
30     
31 
32     //预处理矩阵每一行的值
33     for(i=0;i<m;i++)
34     for(j=0;j<n;j++)
35     for(k=j;k>=0;k--)
36         g[i][j][k]=g[i][j][k+1]+a[i][k];
37     
38     
39     //C中,防止指针值越界,而提前处理初值
40     for(i=0;i<n;i++)
41     for(j=0;j<=i;j++){
42         f[0][j][i]=g[0][j][i];
43         l=max(l,f[0][i][j]);
44     }
45     
46 
47     //求解过程
48     for(i=1;i<m;i++)
49     for(j=0;j<n;j++)
50     for(k=0;k<=j;k++){
51         f[i][j][k]=max(g[i][j][k],f[i-1][j][k]+g[i][j][k]);
52         l=max(l,f[i][j][k]);
53     }
54     
55     printf("%d",l);
56 
57 }

 

posted @ 2013-09-16 20:37  早餐  阅读(224)  评论(1编辑  收藏  举报