相较于上次求最大子矩阵的和,这次明显更难了一些。
将问题分解并分析,可以想到 先求各行中的最大子数组,并记录下标,求完之后再将各行的最大子数组的下标进行比较可以得到两种情况
1.上一行的最大子数组下标范围和下一行的最大子数组下标范围有重合的部分。
2.上一行的最大子数组下标范围和下一行的最大子数组下标范围无重合的部分。
程序代码:
#include<iostream> using namespace std; int calculate(int n,int a[],int &sm,int &mm) { int b[100]={0}; int i,sum1=0,max1=0; for(i=0;i<n;i++) { if(sum1<0) { sum1=a[i]; } else { sum1=sum1+a[i]; } b[i]=sum1; } max1=b[0]; for(i=0;i<n;i++) { if (max1<b[i]) { max1= b[i]; mm = i; } } for (i = mm;i >= 0;i--) { if (b[i] == a[i]) { sm= i; break; } } return max1; } int main() { int row,line,sm,mm,t2,sum,max; int up[10],down[10],t[10],b[10]; cout<<"输入数组的行: "; cin>>row; cout<<"输入数组的列: "; cin>>line; int **a; a = new int*[row]; for(int i=0; i<row;i++) { a[i] = new int [line]; } cout<<"请输入数组元素:"<<endl; for(int i=0;i<row;i++) { for(int j=0;j<line;j++) { cin>>a[i][j]; } } for(int i=0;i<row;i++) { for(int j=0;j<line;j++) { b[j]=a[i][j]; } sum=calculate(line,b,sm,mm); up[i]=sm; down[i]=mm; t[i]=sum; } t2=t[0]; for(int i=0;i+1<row;i++) { if(up[i]<=down[i+1] && down[i]>=up[i+1]) { t2+=t[i+1]; } for(int j=up[i];j<up[i+1];j++) { if(a[i+1][j]>0) { t2+=a[i+1][j]; } } } cout<<"最大联通子数组的和是:"<<t2<<endl; for(int i=0;i<row;i++) { delete [] a[i]; } delete [] a; system("pause"); return 0; }
这次实验尝试了各种方法,都是太复杂的方法,难以实现,这个方法虽然不难,但是还是有缺陷,以后我们会改正。
组员:赵承圣,罗元浩(http://www.cnblogs.com/lyhao/)