poj- 1964 ,uva1330 contesthunter 1803
city game(单调栈)O(n2)
题意:求最大F子矩阵
这一题可以看作二维的单调栈,枚举每一列的高度,然后每一列跑一遍单调栈,主要是处理输入以及矩阵的转换有些麻烦,具体情况请看代码:
#pragma G++ optimize(2)
#pragma GCC optimize(2)
#define DEBUG
#include<iostream>
#include<algorithm>
#include<stack>
#include<vector>
#include<iostream>
#include<climits>
#include<queue>
#include<cassert>
#include<iomanip>
#include<cmath>
#include<string>
#include<cstdio>
#include<cstring>
#define _rep(i, a, b) for(int i = (a); i <= (b); ++i)
#define _rev(i, a, b) for(int i = (a); i >= (b); --i)
#define _for(i, a, b) for(int i = (a); i <(b); ++i)
#define _rof(i, a, b) for(int i = (a); i >(b); --i)
#define maxn 1009
#define maxm 109
#define ll long long
#define met(a,b) memset((a),(b), sizeof(a))
#define db double
#define eps 1e-8
using namespace std;
int map[maxn][maxn];
int n, m, a[maxn], l[maxn], r[maxn], s[maxn];
int solve(int o) {
met(a, 0), met(l, 0), met(r, 0), met(s, 0);
int top = 0, ret = 0;
_rep(i, 1, n) a[i] = map[i][o];
_rep(i, 1, n) {
while (top && a[s[top]] >= a[i])top--;
l[i] = top ? i - s[top] - 1 : i - 1;
s[++top] = i;
}
top = 0;
_rev(i, n, 1) {
while (top && a[s[top]] >= a[i]) top--;
r[i] = top ? s[top] - i - 1 : n - i;
s[++top] = i;
}
_rep(i, 1, n) {
ret = max(ret, a[i] * (1 + r[i] + l[i]));
}
return ret;
}
int main()
{
ios::sync_with_stdio(0);
/*FILE* w = freopen("C:\\Users\\Jason.Z\\Desktop\\out.txt", "w", stdout);
assert(w != NULL);*/
int kase;
cin >> kase;
while (kase--) {
char ch;
string sp;
cin >> n >> m;
met(map, 0);
_rep(i, 1, n) {
int last = 0;
_rep(j, 1, m) {
cin >> sp; ch = sp[0];
if (ch == 'R') {
_for(k, last + 1, j) {
map[i][k] = j - k;
}
last = j;
}
else if (j == m) {
_rep(k, last + 1, j) {
map[i][k] = j - k + 1;
}
}
}
}
int ans = 0;
_rep(i, 1, m) {
ans = max(ans, solve(i));
}
cout << ans * 3 << endl;
}
}