AcWing 152. 城市游戏

有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地。

这片土地被分成N*M个格子,每个格子里写着’R’或者’F’,R代表这块土地被赐予了rainbow,F代表这块土地被赐予了freda。

现在freda要在这里卖萌。。。它要找一块矩形土地,要求这片土地都标着’F’并且面积最大。

但是rainbow和freda的OI水平都弱爆了,找不出这块土地,而蓝兔也想看freda卖萌(她显然是不会编程的……),所以它们决定,如果你找到的土地面积为S,它们将给你3*S两银子。

输入格式

第一行包括两个整数N,M,表示矩形土地有N行M列。

接下来N行,每行M个用空格隔开的字符’F’或’R’,描述了矩形土地。

每行末尾没有多余空格。

输出格式

输出一个整数,表示你能得到多少银子,即(3*最大’F’矩形土地面积)的值。

数据范围

1≤N,M≤1000

输入样例:
5 6
R F F F F F
F F F F F F
R R R F F F
F F F F F F
F F F F F F
输出样例:
45


这题第一眼看起来可以用暴力,但是数据量大时,TLE就在所难免。
这时我们来分析题。
1.要组成最大的矩阵。且只由F构成。
2.组成矩阵,每个F要连续。
所以感觉是不是像最大直方图的面积问题呢。
这个时候我们可以,先统计从第一行到每一行,连续的矩阵个数。记住时连续且包含该行也要是F。
所以可以得出下一行的数量h[i][j] = h[i-1][j] + 1, 如果当前行不是F,则h[i][j] = 0;

然后问题变成枚举每一行,求出最大直方图问题。
代码:

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

const int N = 1010;
int h[N][N];//存储F的数量
char g[N][N];

int s[N], w[N];//s为栈,w时宽度
int n, m;
int work(int a[]) {
		int p = 0;
		a[m+1] = 0;
		int ans = 0;
        for(int i = 1; i <= m+1; ++ i) {
            if(a[i] > s[p]) s[++p] = a[i], w[p] = 1;
            else {
                int width = 0;
                while(s[p] > a[i]){
                    width += w[p];
                    ans = max(ans, width*s[p]);
                    p--;
                }
                s[++p] = a[i], w[p] = width + 1;
            }
        }
        return ans;
}
int main() {
	cin >> n >> m;
	for(int i = 1; i <= n; ++ i)
		for(int j = 1; j <= m; ++ j)
		{
			char c;
			cin >> c;
			g[i][j] = c;
			if(c == 'F') h[i][j] = h[i-1][j] + 1;
			else h[i][j] = 0;
		}

	int ans = 0;
	for(int i = 1; i <= n; ++ i) ans = max(ans, work(h[i]));//枚举每一行
	cout << ans * 3 << endl;
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/rstz/p/13380678.html