HDU

先上题目:

To The Max

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7177    Accepted Submission(s): 3470


Problem Description
Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1 x 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 x 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
 
 
  二维版的求区间最值。
  如果是一维版的话状态转移方程:
  dp[i]=w[i]          ans<=0
     =ans+w[i]   ans>0            其中ans代表当前位置i往前连续的一段的区域最值
  而maxn=max(ans,maxn)           maxn代表总体最值
  对于二维的时候,其实和一维大致相同。这里需要在一个方向上(假设是行数增加的方向)枚举区间,然后在另一个方向上(列数增加的方向)上进行想一维的时候那样的操作。这样做的涵义其实是在某一个确定的区间上,求这个区间上的最值。
  详细需要看代码。
  分析如图:
上代码:
 1 #include <cstdio>
 2 #include <cstring>
 3 #define MAX 101
 4 #define INF ~(1<<31)
 5 using namespace std;
 6 
 7 int s[MAX][MAX];
 8 int h[MAX][MAX];
 9 int dp[MAX][MAX];
10 
11 int main()
12 {
13     int n;
14     int ans,maxn;
15     while(scanf("%d",&n)!=EOF)
16     {
17         memset(s,0,sizeof(s));
18         memset(h,0,sizeof(h));
19         for(int i=1; i<=n; i++)
20         {
21             for(int j=1; j<=n; j++)
22             {
23                 scanf("%d",&s[i][j]);
24                 h[i][j]=h[i][j-1]+s[i][j];
25             }
26         }
27         maxn=-INF;
28         for(int i=1; i<=n; i++)
29         {
30             for(int j=1; j<=i; j++)
31             {
32                 ans=-1;
33                 for(int k=1; k<=n; k++)
34                 {
35                     if(ans>0) ans+=h[k][i]-h[k][j-1];
36                     else ans=h[k][i]-h[k][j-1];
37                     maxn=ans>maxn ? ans : maxn;
38                 }
39             }
40         }
41         printf("%d
",maxn);
42     }
43     return 0;
44 }
1081
  
原文地址:https://www.cnblogs.com/sineatos/p/3560325.html