一.题目
输入一个二维整形数组,数组里有正数也有负数。
求所有子数组的和的最大值。
二.设计思想
第一种方法:首先若要对二维数组进行分析,通常想要把它化简成为一个一维数组。再先求每个一维数组的最大子数组和,并记下每行最大一维子数组的下标。这是就会分两种情况:第一种是行之间的最大子数组是相连的,这时就可以直接相加得到;第二种是不相连的,,这时候就把每行的最大子数组看成一个整体,再使每个最大数组块进行相连,求使其相连的最小代价。最后得到的就是最大联通子数组的和。
第二种方法:在二维整形数组中,数据可能会有正也有负,要求最大值,我们重点关注正数,所以要首先判断二维数组中哪些位置上的数是正数,利用另一个二维数组记录正数的位置,然后判断哪些数是连通的。首先定位这个二维数组中的最大值,然后在分析这个值周围的4个数,联通这4个数中的正数,若全为负数,则查找次大值,并与最大值联通,判断联通前与联通后值得大小,若变小则不联通最大值,若变大则联通最大值,以此类推,直到最大联通子数组怎么联通都比原来的值小。
三.实验代码
#include<iostream> using namespace std; int dp(int array[],int i) { int dp[100][2],j,S; dp[0][0]=array[0]; dp[0][1]=array[0]; for(j=1;j<i;j++) { dp[j][0]=max(dp[j-1][0],dp[j-1][1]); dp[j][1]=max(array[j],(dp[j-1][1]+array[j])); } S=max(dp[i-1][0],dp[i-1][1]); return S; } int main(){ int Array[100][100],len,wid; cin>>len>>wid; for(int i=0;i<wid;i++) { for(int j=0;j<len;j++) { cin>>Array[i][j]; } } int Max[wid],MAX=0; for(int i=0;i<wid;i++) { int temp_Array[len]; for(int ii=0;ii<len;ii++){ temp_Array[ii]=Array[i][ii]; } Max[i]=dp(temp_Array,len); if(i<len-1) { for(int count=i+1;count<wid;count++) { for(int j=0;j<len;j++) { temp_Array[j]=temp_Array[j]+Array[count][j]; } int temp_max=dp(temp_Array,len); Max[i]=max(Max[i],temp_max); } } MAX=max(MAX,Max[i]); } cout<<MAX; return 0; }
运行截图
总结:本次实验使用了二维的数组,第一次使用 在概念上有点模糊。