City Game
hdu1505:http://acm.hdu.edu.cn/showproblem.php?pid=1505
题解:给你一个字符矩阵,里面有R和F两种字符,然后让你找一个最大的子矩阵,这个最大的子矩阵只含有F。
题解:在队友的提示下和上一题的影响,我先处理出每一行,以该行为起点的连续F的高度,然后每一行的情况问题就转化成上一题的问题,然后枚举每一行就可以了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int N=1002; 7 int n,m; 8 char mp[N][N]; 9 int dp[N][N]; 10 int ll[N],rr[N],ans; 11 int main(){ 12 int cas; 13 scanf("%d",&cas); 14 while(cas--){ 15 scanf("%d%d",&n,&m); 16 for(int i=1;i<=n;i++) 17 for(int j=1;j<=m;j++) 18 cin>>mp[i][j]; 19 for(int i=1;i<=m;i++){ 20 int temp=0; 21 for(int j=1;j<=n;j++){ 22 if(mp[j][i]=='F') 23 ++temp; 24 else 25 temp=0; 26 dp[j][i]=temp; 27 } 28 } 29 ans=0; 30 for(int i=n;i>=1;i--){ 31 memset(ll,0,sizeof(ll)); 32 memset(rr,0,sizeof(rr)); 33 dp[i][0]=-1;dp[i][m+1]=-1; 34 for(int j=1;j<=m;j++){ 35 ll[j]=j; 36 if(j==1)continue; 37 int t=j-1; 38 while(dp[i][j]<=dp[i][t]){ 39 ll[j]=ll[t]; 40 t=ll[t]-1; 41 } 42 } 43 for(int j=m;j>=1;j--){ 44 rr[j]=j; 45 if(j==m)continue; 46 int t=j+1; 47 while(dp[i][j]<=dp[i][t]){ 48 rr[j]=rr[t]; 49 t=rr[t]+1; 50 } 51 } 52 for(int k=1;k<=m;k++){ 53 ans=max(ans,(rr[k]-ll[k]+1)*dp[i][k]); 54 } 55 } 56 printf("%d\n",ans*3); 57 } 58 59 }