嗯,题意也很容易理解,让求最大子矩阵,但是有几个字母是可以改变其值的,和前面1505又不一样,算是它的变形吧,没有做过前面两道题的推荐先看一下, 然后再做这个就会感觉简单很多……囧,我是这样做的!嘿嘿
嗯,可以把这个矩阵变成三个不同的矩阵(分别是a,b,c)然后按照1505题的思路做它就OK了!当然如果不会1505的话,可以先做1506
如果1506也没有思路,好吧,你可以看别人的报告了!嘿嘿。。。。。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 1010
#define Max(a,b) (a>b?a:b)
char map[N][N];
int set[N][N];
int l[N],r[N];
__int64 ans;
int n,m;
void dp(int cur)
{
int i;
for(i=1;i<=m;i++)
l[i] = r[i] = i;
for(i=1;i<=m;i++){
while(set[cur][l[i]-1] >= set[cur][i])
l[i] = l[l[i]-1];
}
for(i=m;i>=1;i--){
while(set[cur][r[i]+1] >= set[cur][i])
r[i] = r[r[i]+1];
}
for(i=1;i<=m;i++)
ans = Max(ans,set[cur][i]*(r[i] - l[i] +1));
return ;
}
void dp_init()
{
int i;
for(i=1;i<=n;i++)
if(set[i+1][0] == -2)
dp(i);
return ;
}
void solve(char ch)
{
int i,j;
//memset(set,0,sizeof(set));
set[n+1][0] = -2;
for(i=1;i<=n;i++){
set[i][0]=-1;
for(j=1;j<=m;j++){
if(map[i][j] == ch)
set[i][j] = set[i-1][j] +1;
else if(ch == 'a'){
if(map[i][j] == 'w' || map[i][j] == 'y' || map[i][j] == 'z')
set[i][j] = set[i-1][j] +1;
else {
set[i][0] = -2;
set[i][j] = 0;
}
}
else if(ch == 'b'){
if(map[i][j] == 'w' || map[i][j] == 'x' || map[i][j] == 'z')
set[i][j] = set[i-1][j] +1;
else {
set[i][0] = -2;
set[i][j] = 0;
}
}
else if(ch == 'c'){
if(map[i][j] == 'x' || map[i][j] == 'y' || map[i][j] == 'z')
set[i][j] = set[i-1][j] +1;
else {
set[i][0] = -2;
set[i][j] = 0;
}
}
}
set[i][j] = -1;
}
dp_init();
return ;
}
int main()
{
int i;
while(~scanf("%d%d",&n,&m))
{
for(i=1;i<=n;i++)
scanf("%s",map[i]+1);
ans = 0;
solve('a');
solve('b');
solve('c');
printf("%I64d\n",ans);
}
return 0;
}
本文介绍了一种解决包含可变字母的最大子矩阵问题的方法,通过将矩阵分解为三个不同矩阵并应用类似1505题的算法进行求解。详细解释了如何根据字母变化对矩阵进行处理,并提供了具体的实现代码。适合那些对矩阵操作和动态规划有深入理解的读者。
2391

被折叠的 条评论
为什么被折叠?



