题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4328
题目大意:求同色最大矩形,颜色相间的最大正方形。
题目思路:这种程度的dp都没做出来,我太弱了。。枚举下底,直接处理大左界和右界即可,对于相间的,将行列和为奇数的反转,就转化为同色。话说高度为0的时候要特别注意啊!我开始的处理的方法会让他们的左右界到-1和m,如果不去除这种情况,会得到m*2的答案。。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
//#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define Max 110
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
char mp[2000][2000];
int h[2000],l[2000],r[2000];
int n,m;
int cal(char tp,int kao)
{
int ans=0;
int i,j,tmp;
for(j=0;j<m;j++) h[j]=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(mp[i][j]!=tp) h[j]=0;
else
h[j]++;
}
l[0]=-1;
for(j=1;j<m;j++)
{
if(h[j-1]<h[j]||h[j]==0)
{
l[j]=j-1;
continue;
}
tmp=j-1;
while(l[tmp]!=-1&&h[l[tmp]]>=h[j])
{
tmp=l[tmp];
}
l[j]=l[tmp];
}
r[m-1]=m;
for(j=m-2;j>=0;j--)
{
if(h[j+1]<h[j]||h[j]==0)
{
r[j]=j+1;
continue;
}
tmp=j+1;
while(r[tmp]!=m&&h[r[tmp]]>=h[j])
tmp=r[tmp];
r[j]=r[tmp];
}
for(j=0;j<m;j++)
{
if(h[j]==0) continue;//特别注意啊!和面积不一样。。
if(kao==0)
ans=max(ans,2*h[j]+2*(r[j]-l[j]-1));
else
ans=max(ans,4*min(h[j],r[j]-l[j]-1));
}
}
return ans;
}
int main()
{
int t,count=1,i,j;
scanf("%d",&t);
while(t--)
{
int ans=0;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%s",mp[i]);
ans=cal('B',0);
ans=max(ans,cal('R',0));
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
if(i%2==0&&j%2==1)
{
if(mp[i][j]=='B') mp[i][j]='R';
else mp[i][j]='B';
}
else if(i%2==1&&j%2==0)
{
if(mp[i][j]=='B') mp[i][j]='R';
else mp[i][j]='B';
}
}
ans=max(ans,cal('B',1));
ans=max(ans,cal('R',1));
printf("Case #%d: %d\n",count++,ans);
}
}