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

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;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值