标签:
把前一个问题扩展了一下,寻找二维数组中,从(x1, y1)到(x2, y2)确定的矩形区域的数据之和最大值。
解法一给出了一个技巧,建立一个和原数组一样大的数组,用来保存(0, 0)到(x, y)的和,即P[x][y] = sum(x[0][0] –> x[x][y])。然后用Sum = PS[i_max][j_max] - PS[i_min - 1][j_max] – PS[i_max][j_min - 1] + PS[i_min - 1][i_min -1]。不知道书上为什么要让数组从1开始,然后把数组的边界置0。
解法二用了分治的思想,或者动态规划吧。先假定一个边界,用穷举遍历这些边界,再把选定的数据变换为一维数据,根据上一节的算法进行分析。
扩展问题:
1. 收尾相连后,就只能上下确定边界,然后按照一维的解法进行求解。
2. 上下也相连,就要两个方向都按照首尾相邻的情况考虑了。
3、4. 三维和四维的情况,至少可以先在两个方向上遍历,在另一方向上上先求和再按一维情况求解吧。
1. 简述
给定一个n*n(0<n<=100)的矩阵,请找到此矩阵的一个子矩阵,并且此子矩阵的各个元素的和最大,输出这个最大的值。
Example:
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
最大子矩阵为:
9 2
-4 1
-1 8
2. 原理
最大子矩阵和是最大子序列和的二维扩展。
穷举所有子矩阵的话,有C(n,2)*C(n*2)/2个子矩阵,就是n^4个子矩阵,这还不算每个子矩阵求和的时间,就到了O(n^4)。
转化为最大子序列求解的思路是:固定第i列到第j列的范围,寻找在这个范围内的最大子矩阵,这个寻找过程,把每行第i列上的元素到第j列的元素分别求和,就转变为了一维的情况。由于有C(n,2)种列的组合,而求一维的子序列需要n的时间,所以,总体上时间复杂度为O(n^3)。
3. 递推公式
A的下标从0开始,为了增加哨兵,F,P,Q的下标都从1开始。
· A[N][N]表示输入矩阵。
· F[N+1][N+1],F[i][j]表示从第i行的第0列到第j列的元素和。
F[i][j]=0,j=0
F[i][j]=A[i-1][j-1], j=1
F[i][j]=F[i][j-1]+A[i-1][j-1],j>1
这样当固定第i列到第j列的时候,转化为一维数组的第k个元素就可以表示为F[K][j]-F[K][i-1],K是行下标,i和j都是列下标,由于矩阵的统计是从1开始的,所以i,j,k都是大于等于1的,即i-1不会下标越界,这就是前面哨兵的作用。
固定i列和j列的时候的求解递推公式:
· P[N+1],P[k]表示固定第i列到第j列时,从第1行到第k行范围内,包括第k行的最大子矩阵。
· Q[N+1],Q[k]表示固定第i列到第j列时,从第1行到第k行范围内,最大子矩阵。
P[k]=F[0][j]-F[0][i-1], k=1
P[k]=P[k-1]>0?(P[k-1]+F[k][j]-F[k][i-1]):(F[k][j]-F[k][i-1]),k>1
Q[k]=P[k], k=1
Q[k]=max{Q[k-1], P[k]}, k>1
Q[N]即为固定列(i-j)范围内的最大和。
#include<iostream> #include<vector> #include<math.h> using namespace std; // int Maxval_temp(int* a,int n) { if(n==1) return a[n-1]; int maxall=a[n-1]; int maxstart=a[n-1]; for(int i=n-2;i>=0;i--) { maxstart=max(a[i],a[i]+maxstart); maxall=max(maxall,maxstart); } return maxall; } int MaxVal(vector<vector<int>> vec) { if(vec.empty()) return 0; int m,n; m=vec.size(); n=vec[0].size(); if(m==1) return vec[0][0]; int max_val=vec[0][0]; for(int i=0;i<m;i++) for(int j=i;j<m;j++) { int* ptr=new int[n]; for(int k=0;k<n;k++) { int temp1=0; for(int g=i;g<j;g++) temp1+=vec[k][g]; ptr[k]=temp1; } int temp_max=Maxval_temp(ptr,n); if(temp_max>max_val) max_val=temp_max; } return max_val; } int main() { }
标签:
原文地址:http://www.cnblogs.com/yanliang12138/p/4650712.html