zoj2180 City Game(DP/数据结构)

/*
 zju1985升级版 ^_^ 继上次那道题想了一天,本来想用O(N^2)的最大正方形求解,
 想错了今天仔细一看,其实这道题目就是二维的最大矩形。
 
 分析:我们将问题分解成最大矩形,即求解以k行为底边的图形中的最大矩形,
    然后将问题合并,求出最大的矩形。
   
    预处理: 求出以每行为底边的每一列从底边开始向上的最大高度MaxH。 O(N^2)
    DP;    对于每一层底边,我们利用单调队列求解出本行的最大矩形。 O(N)
       关于单调队列的求解分析,可参照zju1985的题解
    总体时间:T(N) = O(N^2)+O(N)*O(N) = O(N^2)
*/

ContractedBlock.gif ExpandedBlockStart.gif View Code
 1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 char Maps[ 1003 ][ 1003 ];
6 int MaxH[ 1003 ][ 1003 ];
7 int L[ 1003 ],R[ 1003 ];
8 int MUQ[ 1003 ];
9
10 int main()
11 {
12 int t,m,n;
13 while ( scanf("%d",&t) != EOF )
14 while ( t -- ) {
15 scanf("%d%d",&m,&n);getchar();
16 for ( int i = 1 ; i <= m ; ++ i )
17 for ( int j = 1 ; j <= n ; ++ j ) {
18 scanf("%c",&Maps[ i ][ j ]);
19 getchar();
20 }
21
22 //计算每条底边上的每列高度
23 memset( MaxH, 0, sizeof( MaxH ) );
24 for ( int i = 1 ; i <= m ; ++ i )
25 for ( int j = 1 ; j <= n ; ++ j )
26 if ( Maps[ i ][ j ] == 'F' )
27 MaxH[ i ][ j ] = MaxH[ i-1 ][ j ]+1;
28 else
29 MaxH[ i ][ j ] = 0;
30
31 for ( int i = 1 ; i <= m ; ++ i )
32 MaxH[ i ][ 0 ] = MaxH[ i ][ n+1 ] = -1;
33
34 int MaxV = 0;
35 for ( int i = 1 ; i <= m ; ++ i ) {
36 //计算每个点的左边界
37 int tail = 0;
38 MUQ[ 0 ] = 0;
39 for ( int j = 1 ; j <= n+1 ; ++ j ) {
40 while ( tail >= 0 && MaxH[ i ][ MUQ[ tail ] ] > MaxH[ i ][ j ] )
41 R[ MUQ[ tail -- ] ] = j;
42 MUQ[ ++ tail ] = j;
43 }
44 //计算每个点的右边界
45 tail = 0;
46 MUQ[ 0 ] = n+1;
47 for ( int j = n ; j >= 0 ; -- j ) {
48 while ( tail >= 0 && MaxH[ i ][ MUQ[ tail ] ] > MaxH[ i ][ j ] )
49 L[ MUQ[ tail -- ] ] = j;
50 MUQ[ ++ tail ] = j;
51 }
52 //求解
53 for ( int j = 1 ; j <= n ; ++ j ) {
54 int Temp = MaxH[ i ][ j ]*(R[ j ]-L[ j ]-1);
55 if ( MaxV < Temp )
56 MaxV = Temp;
57 }
58 }
59
60 printf("%d\n",MaxV*3);
61 }
62 return 0;
63 }

转载于:https://www.cnblogs.com/-xiaobai-/archive/2011/08/17/2143079.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值