关于二维数组求最大子矩阵的和的想法
因为我们之前做了一个一维数组求最大和的程序,采用暴力枚举法的结果是时间复杂度很高。现在想想,要求二维数组,一维数组的方法是不是也可以套用在其上,其实一维数组的求最大模块的和的方法有很简单,并且时间复杂度为n的,在这各位园友可以学习学习动态规划的方法,在这里就不说了。
我们是不是可以这样做:首先将二维数组看成多个一维数组,分别用一维数组求最大和的方法,求出各组的最大值,最小值的模块,同时标记各模块的(i,j)起始与终止的位置,先以第一行一维数组的最大模块的(i,j)为边界依次加上第二行,第三行……此时会有一个以第一行最大模块为“带头大哥”的最大模块,记录此时为模块1;第二次,以第二行数组的最大和为模块边界,依次加上第三行,第四行……此时会有一个以第二行为“带头大哥”的最大模块,记录为模块2,依次求出模块n,通过比较得出最大模块,此时的模块就应当为整个二维数组的最大模块,有兴趣的园友可以试一试。
一维的数组的求最大和的模块:
int max(int a[],int n) { cur = a[0]; max = a[0]; for i=1 to n-1 do if cur<0 do { cur = 0;ix=i;} {cur += a[i];iy=i;} if cur>max do max = cur; return max; }
其实仔细想想,这也是暴力枚举法的一种,只不过是将枚举的范围在开始时就缩小了,虽然最初想的其实并不是暴力枚举法,希望用复杂度低一点的方法解决它,但是智商压制啊!
不过貌似还有另一种方法:
也是利用上面的一维数组求最大模块的和的函数,首先将二维数组的第一行看成一个一维数组,利用max方法求出最大的模块,然后将二维数组的第1,2两行看成一个一维数组(就是1,2两行对应位置的和看成一个一维数组),再利用max方法求出最大值的模块,依次求出剩下的。再利用max求以第二行为开始的“一维数组”,直至结束。
不过这也是暴力枚举法的一种,只不过是稍微减少了时间复杂度。
队员:汪洋,辛垧
希望各位园友不吝赐教。