1. 程式人生 > >poj1050 dp動態規劃

poj1050 dp動態規劃

翻譯 lan NPU poj 題意 con script const ems

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

poj1050 dp動態規劃