链接:http://acm.hdu.edu.cn/showproblem.php?pid=2870
2 4 abcw wxyz
3
题意:
有若干种 转换字母的方法,问转化后 可以得到的 最大相同字母矩阵 是多大。 矩阵大小= n*m
做法:
全转成a,然后不能的位子是0,可以的位子是1。
然后 deal 里就是一维的最大矩阵 的处理了。 是一种dp。 做法和一维的 hdu 1506 差不多。
然后再把 全是 b和c 的求出来 求最大值就好了。
#pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using namespace std; #include <queue> #include <stack> #include <vector> #include <list> #include <deque> #include <set> #pragma comment(linker, "/STACK:1024000000,1024000000") #include <map> typedef long long LL; const int INF = 1<<10; const LL mod = 95041567; int n,m; char mp[1010][1010]; int toch[30]; int num[1010][1010]; int sum[1010][1010]; int lft[1010];//左边最大连续 int rit[1010];//右边最大连续长度 int deal(int sum[])//算一维 最大子矩阵 { sum[0]=sum[m+1]=-1; for(int i=1;i<=m;i++) { lft[i]=i; while(sum[i]<=sum[lft[i]-1]) lft[i]=lft[lft[i]-1]; } for(int i=m;i>=1;i--) { rit[i]=i; while(sum[i]<=sum[rit[i]+1]) rit[i]=rit[rit[i]+1]; } int ans=0; for(int i=1;i<=m;i++) ans=max((rit[i]-lft[i]+1)*sum[i],ans); return ans; } int solve()//算二维 最大子矩阵 { //前缀和 从 上向下 累加的 for(int i=1;i<=m;i++) sum[0][i]=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(num[i][j]) sum[i][j]=sum[i-1][j]+1; else sum[i][j]=0; } } int ans=0; for(int i=1;i<=n;i++) { ans=max(ans,deal(sum[i])); //cout<<"hang"<<i<<" he"<<deal(sum[i])<<endl; } return ans; } int main() { toch['w']=3; toch['y']=5; toch['x']=6; toch['z']=7; toch['a']=1; toch['b']=2; toch['c']=4; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) scanf("%s",mp[i]+1); int ans=0; for(int k=0;k<3;k++) { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { if(toch[mp[i][j]]&(1<<k)) num[i][j]=1; else num[i][j]=0; } } ans=max(ans,solve());// a b c 分别处理 此时 矩阵为 01 矩阵 找1 最大矩阵 // cout<<"zimu"<<k<<" "<<solve()<<endl; } cout<<ans<<endl; } return 0; } /* 2 4 abcw wxyz */