poj1050 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. In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle. 
As an example, the maximal sub-rectangle of the array: 

0 -2 -7 0 
9 2 -6 2 
-4 1 -4 1 
-1 8 0 -2 
is in the lower left corner: 

9 2 
-4 1 
-1 8 
and has a sum of 15. 

Input

The input consists of an N * N array of integers. The input begins with a single positive integer N on a line by itself, indicating the size of the square two-dimensional array. This is followed by N^2 integers separated by whitespace (spaces and newlines). These are the N^2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in the second row, left to right, etc. N may be as large as 100. The numbers in the array will be in the range [-127,127].

Output

Output the sum of the maximal sub-rectangle.

Sample Input

4
0 -2 -7 0 9 2 -6 2
-4 1 -4  1 -1

8  0 -2

Sample Output

15


题目翻译过来,就是在一个大矩阵里面,找一个(矩阵和最大)的子矩阵。

如题意:
0 -2 -7 0 
9 2 -6 2  9 2
-4 1 -4 1      -4 1
-1 8 0 -2  -1 8 9+2+(-4)+1+(-1)+8  = = 15 所以输出15


做这题之前,先来了解一下    一维数组子串,找连续数组的最大和 例如 2 3 -7 9 2 -6 9 最大和为(9,2,-6,9) -> 14


如何用算法实现,当然用dp 顺推, 假设数组a 只要a的前项与后项的和大于0,保留,继续比较,在这个过程中要存储max的值


正如 上面例子
  2  3   -7  9 2  -6  9    

遍历一遍 (前项加本项等于本项的值,但形成负数的时候,要归零)

 形成 2 5(2+3) 0 (5+-7小于0,归零) 9    11(9+2)   5 (11-6)   14(5+9)


同样本题是这个思想的延伸,扩展到了二维


第一步:
0 -2 -7 0     -> max=0
9 2 -6 2      -> max=11
-4 1 -4 1     -> max=1 四个合起来 ,得max=11
-1 8 0 -2     -> max=8

第二步(二维压缩成一维 ):
第一行与第二行相加保留在第二行,然后继续压缩,最后压缩成了一维。中间过程要与max比较,取较大值.........


AC代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#define Max(a,b) ((a)>(b)?:(a):(b))
#define Min(a,b) ((a)<(b)?:(a):(b))
#define Mem0(x) memset(x,0,sizeof(x))
#define Mem1(x) memset(x,-1,sizeof(x))
#define MemX(x) memset(x,0x3f,sizeof(x))
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
int n,a[1010][1010];
/*
int dp(int b[])
{
	int i,ans=b[0];
	for (i=0;i<n;i++)
		printf("%d\t",b[i]);
	printf("******");
	for (i=0;i<n;i++){
		if (b[i]>0)
			b[i+1]+=b[i];
		if (ans<b[i])
			ans=b[i];
		printf("%d\t",b[i]);
	} 
	printf("%d\t",b[i]);
	return ans;
}*/
int main()
{
	int n;
	while (cin>>n){
	int i,j,k,ans=-inf;
	Mem0(a);
	for (i=0;i<n;i++){
		int tmp=0;
		for (j=0;j<n;j++){
			cin>>a[i][j];
			if (tmp>0)
				tmp+=a[i][j];
			else tmp=a[i][j];
			if (tmp>ans)
				ans=tmp;
		}
	}
	for (i=0;i<n-1;i++){
		for (j=i+1;j<n;j++){
			int tmp=0;
			for (k=0;k<n;k++){
				a[i][k]+=a[j][k];
				if (tmp>0)
					tmp+=a[i][k];
				else
					tmp=a[i][k];
				if (tmp>ans)
					ans=tmp;
			}
		}
	}
	printf("%d\n",ans);
	}
	
//	system("pause");	
	return 0;
}
 
posted @ 2018-07-15 17:48  生活待我如初恋  阅读(330)  评论(0编辑  收藏  举报