题目:
输入一个二维整形数组,数组里有正数也有负数。求所有子数组的和的最大值。
设计思路:
思考半天,却无从下手,在课堂上听老师说先求出部分的最大值,再把他连起来,看如果连接起来比原先的大,就ok,如果小了,就舍去,但是如何连起来不知怎么去写。
实验代码:
#include<iostream> using namespace std; int zuida(int n,int a[],int *sm,int *mm); void main() { int m,n,i,j,sm,mm,t2; int sum,max; int up[100],down[100],t[100]; int a[100][100],b[100]; cout<<"输入二维数组的行"<<endl; cin>>m; cout<<"输入二维数组的行"<<endl; cin>>n; for(i=0;i<m;i++) { for(j=0;j<n;j++) { cin>>a[i][j]; } } for(i=0;i<m;i++) { for(j=0;j<n;j++) { b[j]=a[i][j]; } sum=zuida(n,b,&sm,&mm); up[i]=sma; down[i]=mm; t[i]=sum; } t2=t[0]; for(i=0;i+1<m;i++) { if(up[i]<=down[i+1] && down[i]>=up[i+1]) { t2+=t[i+1]; } for(j=up[i];j<up[i+1];j++) { if(a[i+1][j]>0) t2+=a[i+1][j]; //判别独立正数 } } cout<<t2<<endl; } int zuida(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; }
实验总结;
看了别人的代码,渐渐的明白了。对n*m的二维数组进行分解,分解为n个一维数组,再先求这n个一维数组的最大子数组和,并记下每行最大一维子数组的下标如2-5,这是就会分两种情况第一种是行之间的最大子数组是相连的,如第一行是2-5,第二行是3-6,这是直接相加就行。第二种是不相连的如第一行是2-5,第二行是6-7,这时候就把每行的最大子数组看成一个整体,再使每个最大数组块进行相连,求使其相连的最小代价。最后就可求出最大联通子数组的和。