题意:给一个矩阵,求出元素和最大的子矩阵。
思路:
之前曾写过最大子串和的一篇文章,这次由一维上升到了二维。
我们可以通过累加每行相同列或每列相同行的值,将其储存在一个数组中,便可以将二维降至一维。
时间复杂度为O(n^3)。
参考:
code:
/* *Author : Flint_x *Created Time : 2015-07-23 15:10:01 *File name : POJ1050.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); const int inf = 1000000000; typedef long long lint; #define cls(a) memset(a,0,sizeof(a)) #define rise(i,a,b) for(int i = a ; i <= b ; i++) #define fall(i,a,b) for(int i = a ; i >= b ; i--) const int maxn = 105; int ma[maxn][maxn];//输入矩阵 int total[maxn][maxn];//total[i][j]表示输入矩阵第i-1行的第0列到第j-1列元素之和 int dp[maxn];//dp[i] 表示第i-1行之前,以第i-1行为结尾的最大子矩阵之和 int ans[maxn];//ans[i]表示第i-1行之前的最大子矩阵之和 int finall;//输出答案 int n; void input(){ cin >> n; for(int i = 0 ; i < n ; i++) for(int j = 0 ; j < n ; j++) scanf("%d",&ma[i][j]); } void init(){ cls(ma); cls(total); cls(dp); cls(ans); input(); } void solve(){ for(int i = 1 ; i <= n ; i++){ total[i][1] = ma[i-1][0]; total[i][0] = 0; } for(int i = 1 ; i <= n ; i++){ for(int j = 2 ; j <= n ; j++) { total[i][j] = total[i][j-1] + ma[i-1][j-1]; } // cout << total[i][1] << endl; } finall = ans[n]; for(int i = 1 ; i <= n ; i++){ for(int j = i + 1 ; j <= n ; j++){ dp[1] = total[1][j] - total[1][i-1]; ans[1] = dp[1]; for(int k = 2 ; k <= n ; k++){ dp[k] = max(dp[k-1]+total[k][j]-total[k][i-1] , total[k][j]-total[k][i-1]); ans[k] = max(ans[k-1],dp[k]); } finall = max(finall,ans[n]); } } } int main(){ // freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); init(); solve(); cout << finall << endl; return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ 1050 To the Max(DP,最大子矩阵和)
原文地址:http://blog.csdn.net/qq_15714857/article/details/47024177