题意 求最大相同字符子矩阵 其中一些字符可以转换
其实就是HDU1505 1506的加强版 但是分了a,b,c三种情况 看哪次得到的面积最大
对于某一个情况 可以把该字符和可以转换为该字符的位置赋值0 其它位置赋值1 这样就转化成了求最大全0矩阵的问题了
对于转换后矩阵中的每个点 看他向上有多少个连续0 把这个值存在h数组中 再用l数组和r数组记录h连续大于等于该位置的最左边位置和最右位置 这样包含(i,j)点的最大矩阵面积就是(r[i][j]-l[i][j]+1)*h[i][j] 面积最大的点就是最大全0矩阵了
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1005;
char s[N][N];
int mat[N][N], l[N][N], r[N][N], h[N][N], n, m, ans;
void makeMat (char a, char b, char c)
{
memset (mat, 0, sizeof (mat));
memset (l, 0, sizeof (l));
memset (r, 0, sizeof (r));
memset (h, 0, sizeof (h));
for (int i = 1; i <= n; ++i)
{
h[i][0] = h[i][m + 1] = -1;
for (int j = 1; j <= m; ++j)
{
l[i][j] = r[i][j] = j;
if (s[i][j] == a || s[i][j] == b || s[i][j] == c) mat[i][j] = 1;
if (mat[i][j] == 0) h[i][j] = h[i - 1][j] + 1;
}
}
}
int solve (char a, char b, char c)
{
makeMat (a, b, c);
int aans = 0;
for (int i = 1; i <= n; ++i)
{
for (int j = m; j >= 1; --j)
while (h[i][r[i][j] + 1] >= h[i][j])
r[i][j] = r[i][r[i][j] + 1];
for (int j = 1; j <= m; ++j)
{
while (h[i][l[i][j] - 1] >= h[i][j])
l[i][j] = l[i][l[i][j] - 1];
aans = max (aans, (r[i][j] - l[i][j] + 1) * h[i][j]);
}
}
return aans;
}
int main()
{
while (~scanf ("%d%d", &n, &m))
{
for (int i = 1; i <= n; ++i)
scanf ("%s", s[i] + 1);
ans = max (solve ('x', 'b', 'c'), solve ('a', 'y', 'c'));
ans = max (ans, solve ('a', 'b', 'w'));
printf ("%d\n", ans);
}
return 0;
}
2 4 abcw wxyz
3
HDU 2870 Largest Submatrix(DP),布布扣,bubuko.com
HDU 2870 Largest Submatrix(DP)
原文:http://blog.csdn.net/iooden/article/details/38491987