hdu1081 To the Max

直接暴力枚举所有子矩形至少需要O(n^4)的复杂度,显然这不是一个合理的解决方法。

上述方案忽略了矩形之间的联系,进行了过多不必要的计算。

实际上如果固定矩形的左右边界,则底边在i行的矩形内数值之和与底边在i-1行的矩形的关系为 f[i] = s[i] + max(0, f[i - 1]), s[i]表示当前行对应的数值之和。

本题枚举是切入口,通过枚举把所有矩形分成左右边界固定的矩形族,而后再进行动态规划,可降低复杂度至O(n^3)。

 

acm.hdu.edu.cn/showproblem.php?pid=1081
 
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 typedef __int64 LL;
 7 
 8 const int inf = 0x3f3f3f3f;
 9 const int maxn = 100 + 10;
10 
11 int n;
12 int s[maxn][maxn];
13 
14 int main(){
15     while(~scanf("%d", &n)){
16         memset(s, 0, sizeof s);
17         for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) scanf("%d", &s[i][j]);
18         for(int i = 1; i <= n; i++) for(int j = 1; j <= n; j++) s[i][j] += s[i][j - 1];
19         int ans = -inf;
20         for(int i = 1; i <= n; i++){
21             //enumerate left boundary
22             for(int j = i; j <= n; j++){
23                 //enumerate right boundary
24                 int pre = -inf;
25                 for(int k = 1; k <= n; k++){
26                     //dynamic programming
27                     pre = s[k][j] - s[k][i - 1] + max(0, pre);
28                     ans = max(ans, pre);
29                 }
30             }
31         }
32         printf("%d\n", ans);
33     }
34     return 0;
35 }
View Code

 

posted @ 2015-08-16 16:23  astoninfer  阅读(145)  评论(0编辑  收藏  举报