HDU 1505 dp

//考察点:dp,hdu1506的变形
//思路:我们以每一行为底,分别计算高度,扫描每一行,求的面积的最大值
//提交情况:WA 2次,第一次,在i循环中又用到了i,改成j就行了。第二次,将scanf改成cin就过了,这题的数据比较恶心,会有多余的空格。
//收获:编程要细心一些
//AC code
#include<iostream>
using namespace std;

int k,r,c;
char ch;
int mat[1005][1005];
//用来记录高度
int up[1005][1005];
int height[1005][1005];
int ll[1005];
int rr[1005];

int main(){
	scanf("%d",&k);
	while(k--){
		scanf("%d%d",&r,&c);
		int i,j;
		for(i=1;i<=r;i++){
			for(j=1;j<=c;j++){
				cin>>ch;
				up[i][j]=i;
				if(ch=='R')
					mat[i][j]=1;
				else
					mat[i][j]=0;
			}
		}//end for

		for(i=1;i<=r;i++)
			mat[i][0]=mat[i][c+1]=-1;

		for(i=1;i<=c;i++)
			mat[0][i]=mat[r+1][i]=-1;

		//统计每一行能够到达的高度
		for(j=1;j<=c;j++){
			for(i=1;i<=r;i++){
				if(mat[i][j]==0){
					while(mat[up[i][j]-1][j]==mat[i][j])
						up[i][j]=up[up[i][j]-1][j];
					height[i][j]=i-up[i][j]+1;
				}else{
					height[i][j]=0;
				}
			}
		}
		//知道高度后,可以转化为hdu1506的问题
		for(i=1;i<=c;i++){
			ll[i]=i;
			rr[i]=i;
		}
		for(i=1;i<=r;i++)
			height[i][0]=height[i][c+1]=-1;
		
		//遍历每一行
		int max=-1;
		for(i=1;i<=r;i++){
			//从左向右扫描
			for(j=1;j<=c;j++){
				if(mat[i][j]==0){
					while(height[i][j]<=height[i][ll[j]-1])
						ll[j]=ll[ll[j]-1];
				}
			}
			//从右向左扫描
			for(j=c;j>=1;j--){
				if(mat[i][j]==0){
					while(height[i][j]<=height[i][rr[j]+1])
						rr[j]=rr[rr[j]+1];
				}
			}
			//统计
			for(j=1;j<=c;j++){
				if(mat[i][j]==0){
					if((rr[j]-ll[j]+1)*height[i][j]>max)
						max=(rr[j]-ll[j]+1)*height[i][j];
				}
			}
			//恢复初始值
			for(j=1;j<=c;j++){
				ll[j]=j;
				rr[j]=j;
			}
			for(j=1;j<=r;j++)
				height[j][0]=height[j][c+1]=-1;
		}
		if(max!=-1)
			printf("%d\n",3*max);
		else
			printf("0\n");
	}
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值