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

你可能感兴趣的:(编程,c,UP)