结对成员 张永 吴盈盈
本次结对作业和上一次在数组中求最大子数组的作业类似,只是把难度加到了二维。这次我们在课上没有再去考虑一开始的穷举的思想,而是按照上一题动态规划的思路继续推广到二维数组。
我们将每一列都看为是一个元素,这样可以将二维数组看做一个一维数组,设一列中其实的行的为s,结尾的行为e,假设这个数组为B,则B[j]=array[s][j]+....+array[e][j]
其间的部分和就是PSum[e][j]-PartSum[s-1][j]-PSum[e][j-1]+PSum[e-1][j-1],行列都确定下来可以求出部分和再对部分和进行比较。
很遗憾这种算法我们没能自己写出来,参考了网上了一段代码贴在下面。
#include <iostream> using namespace std; #define N 5 #define M 4 int Sum(int (*PSum)[M+1],int istart,int iend,int j) //istart--iend第j列的和 { int pSum; pSum=PSum[iend][j]-PSum[istart-1][j]-PSum[iend][j-1]+PSum[istart-1][j-1]; return pSum; } //求二维数组的连续子数组之和的最大值 int MaxSum(int (*a)[M]) { int PSum[N+1][M+1]; int i,j; for(i=0;i<=N;i++) PSum[i][0]=0; for(j=0;j<=M;j++) PSum[0][j]=0; for(i=1;i<=N;i++) for(j=1;j<=M;j++) PSum[i][j]=PSum[i-1][j]+PSum[i][j-1]-PSum[i-1][j-1]+a[i-1][j-1]; int MaxSum=INT_MIN; int Start,All; int istart,iend; for(istart=1;istart<=N;istart++) { for(iend=istart;iend<=N;iend++) { Start=Sum(PSum,istart,iend,M); All=Sum(PSum,istart,iend,M); for(j=M-1;j>=1;j--) { if(Start>0) Start+=Sum(PSum,istart,iend,j); else Start=Sum(PSum,istart,iend,j); if(Start>All) All=Start; } if(All>MaxSum) MaxSum=All; } } return MaxSum; } int main() { int a[N][M]={ 1,2,3,8, 4,0,-2,11, -8,2,2,2, 9,3,-4,5, 5,4,-4,3 }; int maxSum=MaxSum(a); cout<<maxSum<<endl; getchar(); return 0; }
参考下涨涨姿势吧。