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 }