POJ 1050 To the Max(DP,最大子矩阵和)

POJ 1050

题意:给一个矩阵,求出元素和最大的子矩阵。

思路:

之前曾写过最大子串和的一篇文章,这次由一维上升到了二维。

我们可以通过累加每行相同列或每列相同行的值,将其储存在一个数组中,便可以将二维降至一维。

时间复杂度为O(n^3)。

参考:

累加每一行相同列的做法(java实现)

累加每一列相同行的做法(C++实现)

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;
}
        

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-05 18:57:23

POJ 1050 To the Max(DP,最大子矩阵和)的相关文章

POJ 1050 To the Max DP题解

一维最大字段和的扩展. 要诀是固定列的左右点,比如左边记录为left, 右边记录为right,那么一个循环left从0到COL,行最大值,那么right从left开始循环到COl,就可以考虑到所有列组合了,这个循环是O(n*n),然后求范围列内的行最大子段和,时间是O(n), 这样巧妙地把二维的问题转化为一维了,最终时间复杂度是O(n^3). 可以参考Geeks上的讲解,不过他的最大子段和代码写的挺挫的,我的代码会简洁很多,而且也考虑到了负值情况了. Geeks地址:http://www.gee

[poj]1050 To the Max dp

Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. I

hdu 1081 &amp; poj 1050 To The Max(最大和的子矩阵)

转载请注明出处:http://blog.csdn.net/u012860063 Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum

HDU - 1003 - Max Sum &amp;&amp; POJ - 1050 - To the Max (经典DP问题)

题目传送:HDU - 1003 思路:最大子序列和 dp[i]= a[i]   (dp[i-1]<0) dp[i]= dp[i-1]+a[i]   (dp[i-1]>=0) AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #include <queue> #include

poj - 1050 - To the Max(dp)

题意:一个N * N的矩阵,求子矩阵的最大和(N <= 100, -127 <= 矩阵元素 <= 127). 题目链接:http://poj.org/problem?id=1050 -->>将二维压缩为一维,对一维进行dp求解. 将二维压缩成一维: 1.第1行 2.第2行加第1行 3.第3行加第2行加第1行 -- N.第N行加第N-1行加--加第1行 1.第2行 2.第3行加第2行 -- 1.第N行 对于一维情况,设dp[i]表示以第i个元素结尾的最大连续和,则状态转移方程为

poj 1050 To the Max(线性dp)

题目链接:http://poj.org/problem?id=1050 思路分析: 该题目为经典的最大子矩阵和问题,属于线性dp问题:最大子矩阵为最大连续子段和的推广情况,最大连续子段和为一维问题,而最大子矩阵为二维问题, 可以考虑将二维问题转换为一维问题,即变为最大子段和问题即可求解: 先考虑暴力解法,暴力解法需要枚举子矩阵的左上角元素的坐标与子矩阵的右下角坐标即可枚举所有的子矩阵:对于每个子矩阵,考虑压缩子矩阵的每一列 元素,即求每一列的元素的和,这样子矩阵就转换为一维的情况,再使用最大子段

POJ 1050 To the Max 枚举+dp

大致题意: 求最大子矩阵和 分析: 一开始想复杂了,推出了一个状态方程:d[i][j]=max(d[i][j-1]+…,d[i-1][j]+…).写着写着发现上式省略的部分记录起来很麻烦. 后来发现n最大100,干脆直接枚举行,先枚举所有行的情况,然后将矩阵压缩为数列,最后用最大子段和求解.写着写着感觉就会超时,毕竟出现了四层循环嵌套.结果过了,说明测试数据有点水. #include <iostream> #include <cstdio> #include <cmath&g

hdu 1081 &amp;amp; poj 1050 To The Max(最大和的子矩阵)

转载请注明出处:http://blog.csdn.net/u012860063 Description Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum

POJ 1050 To the Max 最详细的解题报告

题目来源:To the Max 题目大意:给定一个N*N的矩阵,求该矩阵中的某一个矩形,该矩形内各元素之和最大,即最大子矩阵问题. 解题方法:最大子序列之和的扩展 解题步骤: 1.定义一个N*N的矩阵state,state[j][k]用来存放矩阵的某行中第j到k个元素的最大值: 2.对于行如何处理呢?我们可以将第一行中的N个元素的所有组合的最大值存放在state中,如果有哪个值小于0,清零,因为它没有做任何贡献:定计算第二行时与第一行的值(全部大于等于0)进行累加,这样就完成了第一行与第二行的累