hdu2870 Largest Submatrix 单调栈

描述

就不需要描述了...

题目传送门


题解

被lyd的书的标签给骗了(居然写了单调栈优化dp??)  看了半天没看出来哪里是单调队列dp,表示强烈谴责QAQ

w x y z  可以各自 变成a ,b c 中的几种, 那么只需要考虑矩阵由 a, b 或 c 构成就可以了。

对于每一种情况都枚举一次, 比如现在考虑由 a 构成的矩阵, 只需要将能 w y z a 的位置记为 1, 其他位置记为 0 ,然后找面积最大的 由 1 组成的矩阵即可。

那么这题就是道 单调栈裸题了  (   不会的同学可以去这边学

代码

我的单调栈好像有点丑。。。

 1 #include<cstring>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<stack>
 5 #define rd read()
 6 #define rep(i,a,b) for( int i = (a); i <= (b); ++i )
 7 #define per(i,a,b) for( int i = (a); i >= (b); --i )
 8 using namespace std;
 9 
10 const int N = 1e3 + 5;
11 
12 char s[N][N];
13 
14 int n, m, mp[N][N], ans, h[N], pre[N], nxt[N];
15 
16 stack<int> st;
17 
18 void cal() {
19     memset(h, 0, sizeof(h));
20     rep( i, 1, n ) {
21         rep( j, 1, m ) 
22             if( mp[i][j] ) h[j]++;
23             else h[j] = 0;
24         while( st.size() ) st.pop();
25         rep( j, 1, m ) {
26             int pr = 0;
27             while( !st.empty() ) {
28                 pr = st.top();
29                 if( h[pr] >= h[j] ) st.pop();
30                 else break;
31             }
32             st.push(j);
33             pre[j] = pr;
34         }
35 
36         while( st.size() ) st.pop();
37         per( j, m, 1 ) {
38             int nt = m + 1;
39             while( !st.empty() ) {
40                 nt = st.top();
41                 if( h[nt] >= h[j] ) st.pop();
42                 else break;
43             }
44             st.push(j);
45             nxt[j] = nt;
46         }
47         rep( j, 1, m ) {
48             int len = nxt[j] - pre[j] - 1;
49             ans = max( ans, len * h[j] );
50         }
51     }
52 }
53 
54 int main()
55 {
56     while( scanf("%d%d",&n,&m) == 2 ) {
57         ans = 0;
58         rep( i, 1, n ) scanf("%s",s[i] + 1);
59         rep( i, 1, n ) rep( j, 1, m ) {
60             if( s[i][j] == 'w' || s[i][j] == 'y' || s[i][j] == 'z' || s[i][j] == 'a' ) mp[i][j] = 1;
61             else mp[i][j] = 0;
62         }
63         cal();
64         rep( i, 1, n ) rep( j, 1, m ) {
65             if( s[i][j] == 'w' || s[i][j] == 'x' || s[i][j] == 'z' || s[i][j] == 'b' ) mp[i][j] = 1;
66             else mp[i][j] = 0;
67         }
68         cal();
69         rep( i, 1, n ) rep( j, 1, m ) {
70             if( s[i][j] == 'x' || s[i][j] == 'y' || s[i][j] == 'z' || s[i][j] == 'c' ) mp[i][j] = 1;
71             else mp[i][j] = 0;
72         }
73         cal();
74         printf("%d\n", ans);
75     }
76     return 0;
77 }
View Code

 

 

猜你喜欢

转载自www.cnblogs.com/cychester/p/9478857.html