title: How to find the sum of the largest sub-arrays in a two-dimensional array.
Scenario One: Brute force-enumeration method. For a two-dimensional array we enumerate the size of each sub-array value and then compare it so that we can get the maximum.Its time complexity is: O (the time complexity of n*n*m*m*sum) [N denotes the number of rows, M represents the number of columns, and sum is for the solution sub-matrix]. Because the SUM function is also used in loops, this time complexity is quite large.
Scenario Two:The calculation of the partial and partial computations of the sub-matrices with the upper left-hand corner and the current element (I,J) as vertex pairs is calculated as shown in (a), as we can see:with (I_min,j_min), (I_min,j_max), (I_max,j_min), (I_max,j_max) The elements of the rectangular region as vertices and as: sum[i_max][j_max] = sum[i_max][j_max]- Sum[i_min-1][j_max]-sum[i_max][j_min-1]+sum[i_min-1][j_min-1]. That is, the sum of the elements of any rectangle can be obtained within 0 (1) of the time, based on the known part and.
So how to get parts and what?
Second, the new "partial and" can also be obtained with O (1) on a smaller "partial and" basis.The formula is: sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+
arr[i][j] Here Arr[i][j] is the value of arr[i][j in the matrix.So here we can use O (n*m) to get a partial and. Here we mainly remove the computational method matrix and the time complexity,so the complexity of the time is: O (n*n*m*m).Compared with the programme one has improved.
Figure A figure II
Scenario Three: in fact, we think carefully, we can find that its simplest prototype is to find the maximum value in a one-dimensional array. So, based on this heuristic, we can transform the problem from two-dimensional to one-dimensional to improve the performance of the algorithm. Assuming that the upper and lower bounds of the matrix region have been determined, knowing that the upper and lower boundary distributions of the matrix region are rows A and C, the elements between row A and line C of each column are treated as a whole. An array:(Merge[1],merge[2],merge[3] ...). merge[i]=arr[a][i]+arr[b][i]+. +arr[c][i].
So we can enumerate the upper and lower bounds of the rectangle, and then use a one-dimensional case method to determine the left and right boundary, equivalent to one-dimensional array of an element (through the sub-matrix part and can be calculated in O (1) time the sum of the whole), you can get the solution of the two-dimensional problem. the time complexity of the new method is: O (n*n*m) =o (n*n*n). the process is shown in three examples:
Might
The specific implementation code for scenario one:
int arr[n][m];int max (int x,int y)//Gets the maximum value; {return (x>y)? X:y;} int Sum (int imin,int imax,int jmin,int jmax)//Get the sum of the sub-matrices, the time complexity is O (n*n); {int sum=0;for (int i=imin;i<=imax;i++) for (int j= jmin;j<jmax;j++) Sum+=arr[i][j];return sum;} int maxsum (int *arr,int m,int N)//Gets the maximum value of the sub-matrix; {int maximum=0;for (int i_min=1;i_min<=n;i_min++) for (int i_max=i_min;i_ max<=n;i_max++) for (int j_min=1;j_min<=m;j_max++) for (int j_max=j_min;j_max<=m;j_max++) Maximum=Max ( Maximum,sum (I_min,i_max,j_min,j_max)); return maximum;}
The specific implementation code of scenario two:
int Arr[n][m];int sum[n][m];//Stores the part and the array; int max (int x,int y)//Gets the maximum value; {return (x>y)? X:y;} void Getsum ()//preprocessing gets partial and; {for (int i=0;i<=n;i++) sum[i][0]=0;//boundary value; for (int j=0;j<=n;j++) sum[0][j]=0;//boundary value The real part and data are from sum[1][1]; for (i=1;i<=n;i++) for (j=1;j<=m;j++) sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1 ]+arr[i][j]}inline int Sum (int i_min,int i_max,int j_min,int j_max)//Call more frequently, can be set to inline function, improve efficiency. Compared with scheme one, its time complexity is O (1). {return sum[i_max][j_max]-sum[i_min-1][j_max]-sum[i_max][j_min-1]+sum[i_min-1][j_min-1];} int maxsum (int *arr,int m,int n) {int maximum=0;for (int i_min=1;i_min<=n;i_min++) for (int i_max=i_min;i_max<=n;i_ max++) for (int j_min=1;j_min<=m;j_max++) for (int j_max=j_min;j_max<=m;j_max++) Maximum=max (Maximum,sum (I_min, I_max,j_min,j_max)); return maximum;}
Specific implementation code for scenario three:
#include <iostream> #include <algorithm> using namespace std; #define LEN 888 int Arr[len][len]; Long Long sum[len][len]; Inline long long matrixsum (int s, int t, int i, int j) {return sum[i][j]-sum[i][t-1]-sum[s-1][j]+sum[s-1][t-1]; } int main () {int row, col, I, J; cout<< "Please input the row and the col of the array:" <<endl;cin >> row >> col; cout<< "Please input the data of the array:" <<endl;for (I=1; i<=row; i++)//input data; for (j=1; j<=col; j + +) cin >> Arr[i][j]; for (i=0; i<=row; i++)//Set boundary line; sum[i][0] = 0; for (j=0; j<=col; j + +) Sum[0][j] = 0; for (I=1; i<=row; i++)//pre-processing compute matrix part and for (j=1; j<=col; j + +) Sum[i][j] = arr[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1 ][J-1]; int A, C; Long Long maxsum = arr[1][1]; The setting of the initial value; for (a=1; a<=row; a++) for (c=a; c<=col; C + +)//Set sub-matrix upper and lower bounds to row A and line C, fetch maximum value {long Long Tail = Matrixsum (A, 1, c, 1); Merge columns; for (j=2; j<=col; j + +)//Enumerate backwards by one-dimensional array; {Tail = Max (Matrixsum (A, J, C, J), Matrixsum (A, J, C, J) +tail); Maxsum = Max (Tail, maxsum); }} cout << "Maximum sub-matrix and for:" << maxsum<<endl; System ("pause"); return 0;}
The results of the operation are as follows:
extension Question 1: If a two-dimensional array is connected to the end of the line, like a tape that is connected to the tail, how does the algorithm change?
The implementation code is as follows:
#include <iostream> #include <algorithm> using namespace std; #define LEN 1003 int Arr[len][len]; Long Long sum[len][len]; Inline long long matrixsum (int s, int t, int i, int j) {return sum[i][j]-sum[i][t-1]-sum[s-1][j]+sum[s-1][t-1]; } int main () {int row, col, I, J; cout<< "Please input the row and the col of the array:" <<endl;cin >> row >> col; cout<< "Please input the data of the array:" <<endl; For (I=1, i<=row; i++) for (j=1; j<=col; j + +) cin >> Arr[i][j]; for (i=0; i<=row; i++) sum[i][0] = 0; for (j=0; j<=col; j + +) Sum[0][j] = 0; Calculate the part of the Matrix and for (I=1; i<=row; i++)//compute part and; for (j=1; j<=col; j + +) Sum[i][j] = Arr[i][j]+sum[i-1][j]+sum[i][j-1]-s UM[I-1][J-1]; int A, C; Long Long maxsum = arr[1][1]; The upper and lower bounds do not cross the nth and 1th lines for (a=1; a<=row; a++) for (c=a; c<=row; C + +) {//the sub-matrix upper and lower bounds are set to line A and line C//The left and right borders do not cross the columns m and 1th Long Long Tail = Matrixsum (A, 1, c, 1); for (j=2; j<=col; J + +) {TaIl = max (Matrixsum (A, J, C, J), Matrixsum (A, J, C, J) +tail); Maxsum = Max (Tail, maxsum); A long long Sum = Matrixsum (A, 1, c, 1); The left and right borders will cross the nth and 1th columns long long Start = Sum; int sind = 1; for (i=2; i<=col; i++) {Sum + = Matrixsum (A, I, C, i); if (Sum > Start) {start = Sum; sind = i;} } Tail = Matrixsum (A, col, C, col); int tind = col; for (J=COL-1; j>=1; j--) {Sum + = Matrixsum (A, J, C, J); if (Sum > Tail) {Tail = sum; tind = j;} } if (Sind<tind && start+tail>maxsum) maxsum = Start+tail; } cout << "Maximum sub-matrix and for:" << maxsum<<endl; System ("pause"); return 0;}
extension Problem 2: the 3-dimensional matrix, which is the maximum value of the box neutron box?
Box we need to find the maximum value of the sub-box, then you can imagine! In fact, the idea and the two-dimensional is the same, mainly to take the idea of dimensionality reduction, so that the complex problems can be simplified. The main key is still in the partial and, its solution formula is as follows:
Ps[i][j][k] = a[i][j][k]+ps[i-1][j][k]+ps[i][j-1][k]+ps[i][j][k-1]-ps[i-1][j-1][k]-ps[i-1][j][k-1]-ps[i][j-1 ][K-1]+PS[I-1][J-1][K-1]; [I,j,k image can be represented by their length and width height respectively]
Its time complexity is: O (n*n*m*m*q) =o (n^5). It can be concluded that one dimension is O (N), the two dimensions are O (n*n), and the three-dimensional is O (n^5).
The specific implementation code is as follows:
#include <iostream> #include <algorithm> using namespace std; #define LEN int Arr[len][len][len]; int Sum[len][len][len]; inline int maxcubesum (int a, int b, int c, int d, int i, int j) {return sum[b][d][j]-sum[a-1][d][j]-sum[b][c-1][j]-sum[ b][d][i-1]+ Sum[a-1][c-1][j]+sum[a-1][d][i-1]+sum[b][c-1][i-1]-sum[a-1][c-1][i-1]; } int main () {int row, col, High, I, J, K; cout<< "Please input the row, col and high of the array:" <<endl;cin >> row >> Col >>high; cout<< "Please input the data of the array:" <<endl; For (I=1, i<=row; i++) for (j=1; j<=col; j + +) for (k=1; k<=high; k++) cin >> Arr[i][j][k]; For (i=0, i<=row; i++) for (j=0; j<=col; j + +) sum[i][j][0] = 0; For (i=0, i<=row; i++) for (k=0; k<=high; k++) sum[i][0][k] = 0; for (j=0; j<=col; j + +) for (k=0; k<=high; k++) sum[0][j][k] = 0; Calculates the part of the box and for (I=1; i<=row; i++) for (j=1; j<=col; j + +) for (k=1; K<=high k++) Sum[i][j][k] = arr[i][j][k]+sum[i-1][j][k]+sum[i][j-1][k]+sum[i][j][k-1]-sum[i-1][j-1][k]-sum[i-1][j][k-1]- SUM[I][J-1][K-1]+SUM[I-1][J-1][K-1]; int A, B, C, D; int maxsum = arr[1][1][1]; Limit the range of values for the first dimension for (a=1; a<=row; a++) for (b=a; b<=row; b++)//Limit the value range for the second dimension for (c=1; c<=col; C + +) for (d=c; d <=col; d++) {//Only the last dimension left is not determined, the one-dimensional part is used and the method int Tail = Maxcubesum (a,b,c,d,1,1); for (j=2; j<=k; J + +) {int cur = maxcubesum (a,b,c,d,j,j); Tail = max (tail+cur, cur); Maxsum = Max (Tail, maxsum); }} cout << "Maximum sub-matrix and for:" << maxsum<<endl; System ("pause"); return 0;}
The charm of numbers: The maximal value of the sum of the sub-arrays [two-dimensional]+[three-dimensional]