UVA - 1330 City Game

题目大意:给你一个1000*1000的'R','F'组成的矩阵,求里面全是'F'的最大矩形面积。

解题思路:dp,单调队列。zoj2180。

            本来想用O(N^2)的最大正方形求解,想错了今天仔细一看,其实这道题目就是二维的最大矩形;

            我们将问题分解成最大矩形,即求解以k行为底边的图形中的最大矩形,然后合并,求最大的矩形;
          
            预处理: 求出以每行为底边的每一列从底边开始向上的最大连续1的高度MaxH。 O(N^2) ;

            dp:对于每一层底边,我们利用单调队列求解出本行的最大矩形。 O(N);

            关于单调队列的求解分析,可参照zoj1985的题解;

            总体时间:T(N) = O(N^2)+O(N)*O(N) = O(N^2)。

#include <cstdio>
#include <algorithm>
using namespace std;

int main() {
	int T;
	scanf("%d", &T);
	while (T--) {
		int m, n, ans = 0, mat[1010], right[1010], up[1010] = {0}, left[1010] = {0};
		scanf("%d%d", &m, &n);
		for (int i = 0; i < m; i++) {
			int lo = -1, ro = n;
			for (int j = 0; j < n; j++) {
				char ch = getchar();
				while (ch != 'F' && ch != 'R') ch = getchar();
				mat[j] = ch == 'F' ? 0 : 1;

				if (mat[j] == 1) {
					up[j] = left[j] = 0;
					lo = j;
				} else {
					up[j] = up[j] + 1;
					left[j] = max(left[j], lo + 1);
				}
			}

			for (int j = n - 1; j >= 0; j--)
				if (mat[j] == 1) {
					right[j] = n;
					ro = j;
				} else {
					right[j] = i == 0 ? ro - 1 : min(right[j], ro - 1);
					ans = max(ans, up[j] * (right[j] - left[j] + 1));
				}
		}
		printf("%d\n", ans * 3);
	}
	return 0;
}


你可能感兴趣的:(UVA - 1330 City Game)