求二维数组最大子数组的和。郭林林&胡潇丹
求二维数组子数组的最大值,开始思路不太清晰。先从最简单的开始。
以2*2的简单数组为例找规律,
假设最大数为a[0][0],则summax=a[0][0],比较a[0][0]+a[0][1]、a[0][0]+a[1][0]、a[0][0]+a[0][1]+a[1][0],最后求出summax;
3*3 的数组同理:
假设最大值为a[0][0],则summax=a[0][0],比较a[0][0]所在行和列的最大子数组,取大的赋值给summax,接着扩充数组,继续比较,求出summax;
m*n 的数组即为:
先求出数组中的最大值a[i][j],将它赋值给summax(最大子数组之和);
然后在a[i][j]所在行上,进行扩展,找到行上的最大行的连续数组;
同理,在所在列上继续寻找,找到列上的最大连续数组;
然后以找到的行列数组为框架,继续寻找更大的子数组;
依次比较,最终求出最大子数组的和。
程序实现:
1 //求二维数组的连续子数组之和的最大值 2 int MaxSum(int (*array)[N]) 3 { 4 int PartSum[N+1][M+1]; 5 int i,j; 6 for(i=0;i<=N;i++) 7 PartSum[i][0]=0; 8 for(j=0;j<=M;j++) 9 PartSum[0][j]=0; 10 for(i=1;i<=N;i++) 11 for(j=1;j<=M;j++) 12 PartSum[i][j]=PartSum[i-1][j]+PartSum[i][j-1]-PartSum[i-1][j-1]+array[i-1][j-1]; 13 int MaxSum=-INFINITY;//初始化 14 int imin,imax,jmin,jmax; 15 for(imin=1;imin<=N;imin++) 16 for(imax=imin;imax<=N;imax++) 17 for(jmin=1;jmin<=M;jmin++) 18 for(jmax=jmin;jmax<=M;jmax++) 19 MaxSum=MaxNum(MaxSum,PartSum[imax][jmax]-PartSum[imin-1][jmax]-PartSum[imax][jmin-1]+PartSum[imin-1][jmin-1]); 20 21 return MaxSum; 22 } 23 24 25 26 #include<iostream> 27 using namespace std; 28 int maxSum(int *a, int hang, int lie) 29 { 30 int sum=0; 31 for(int i=0;i<hang;i++) 32 { 33 for(int j=0;j<lie;j++) 34 { 35 for(int k=i;k<hang;k++) 36 { 37 for(int l=j;l<lie;l++) 38 { 39 sum = 0; 40 for(int n=i; n<=k;tn++) 41 for(int m=j; m<=l;m++) 42 { 43 sum += a[n*lie+m]; } 44 b= max(sum,b); 45 } 46 } 47 } 48 } 49 cout<<"最大的子数组和:"<<b<<endl; 50 } 51 int main() 52 { 53 int a[4][4]={{3,-2,5,1},{2,4,2,-6},{1,1,4,2},{1,-4,3,0}}; 54 maxSum( a, 2,3); 55 }