poj1050 dp動態規劃
阿新 • • 發佈:2018-07-15
翻譯 lan NPU poj 題意 con script const ems
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.
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 the sum of the maximal sub-rectangle.
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
Output
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