HPU——6001———预处理——dp

版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/82389652

1.PNG

2.PNG

3.PNG

题目原链接:http://net.hpuacm.cf/problem/6001

这道题也是一道需要预处理的问题,分别用两个数组来记录水平方向上的每个点身后的最多不相同连续字母个数,一个记录垂直的个数,然后再分别计算,具体的在代码中注释

代码:

#include<bits/stdc++.h>

using namespace std;

const int inf=0x3f3f3f3f;
const int maxn=110;
int dp1[maxn][maxn];// 用来记录在水平方向上dp1[i][j]这个位置右边有多少连续的不相同字母,下面的那个记录的是垂直方向的 
int dp2[maxn][maxn];
int vis[30];//用来记录在这一行或者这一列里面是否出现重复的字母 
char str[maxn][maxn];

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m;
		scanf("%d %d",&n,&m);
		for(int i=1;i<=n;i++)
		{
			scanf("%s",str[i]);
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;++j)
			{
				dp1[i][j]=dp2[i][j]=0;
				memset(vis,0,sizeof(vis));
				for(int p=0;;p++)
				{
					if(vis[str[i][j+p]-'A']||j+p>m) break;
					vis[str[i][j+p]-'A']=1;
					dp1[i][j]++;
				}
				memset(vis,0,sizeof(vis));
				for(int p=0;;p++)
				{
					if(vis[str[i+p][j]-'A']||i+p>n) break;
					vis[str[i+p][j]-'A']=1;
					dp2[i][j]++;
				}
			}
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				for(int k=0;k<dp2[i][j];k++)//k是用来遍历在i,j这个位置时垂直方向上的长度 , 
				{
					int cnt=inf;//cnt用来记录最短的水平长度 
					for(int p=0;p<=k;p++)
					{
						cnt=min(cnt,dp1[i+p][j]);
					}
					int res=k+1;//这里是保证在竖直方向上最大不会超过i、j这个位置在数值方向上最大长度 
					for(int p=0;p<cnt;p++)
					{
						res=min(res,dp2[i][j+p]);
					}
					ans=max(ans,res*cnt);
				}
			}
		}
		cout<<ans<<endl;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_41670466/article/details/82389652