POJ1964/UVALive 3029 -City Game -求最大子矩形-(暴力枚举/dp)

给n*m的地图,只有R/F,求最大的F矩形面积(就是个数),输出答案*3


n,m<=1000

看到三秒。。。大胆尝试一下跑n^3。。。。结果居然在uva卡过了。。2s...


先n^2预处理一下,给这个n*m矩阵涂色:

初始化计数器cnt=0

第一个如果是F,涂颜色++cnt,然后往后遍历,如果是R跳过,如果是F,看和前面一个位置是否也是F,是的话,涂和上一个位置一样的颜色,否则涂新的颜色(++cnt)

这样处理完之后。对于第k行,我们要判断i到j列是否全是F,只需要判断   col[k][i]==col[k][j](当然不能是零)


因此我们m^2枚举最优矩形所在的列数i,j, 然后每一次枚举 用o(n) 找出最优矩形所在的行数,便是答案


uvaLA的题非常坑。。。这题读入用scanf(“%c”)会wa。。估计有多余的空格之类的。。。该成%s就ac 了。。。


发现n^3在uva是2s卡过,在poj是tle。。估计是加强数据了

n^2的解法(dp)和 http://blog.csdn.net/viphong/article/details/47985285  这题类似,该题是求 一维上的最大面积,本题是二维,


我们用up[i][j]表示第i行第j列  这个空格 能往上延伸的最大长度(包括自身)

ll[i][j]表示向左延伸最大长度,rr【i】【j】同理,我们可以n^2得到这三个数组


然后我们n^2枚举每一个格子,更新答案即可,

int ret=up[i][j]*(1+ll[i][j]+rr[i][j]);
if (ret>maxx) 
maxx=ret;


dp n^2:


#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001; 

char mp[1005][1005];
int up[1005][1005]; 
int ll[1005][1005];
int rr[1005][1005];

int main()
{
	int n,s; 
	int t;
	cin>>t;
	while(t--)
	{
		memset(up,0,sizeof(up));
		memset(ll,0,sizeof(ll));
		memset(rr,0,sizeof(rr));
		int n,m;
		int i,j,k;
		cin>>n>>m;
		getchar();
		char sss[10];
		for (i=1;i<=n;i++)
		{
			for (j=1;j<=m;j++)
			{
				scanf("%s",sss);
				mp[i][j]=sss[0];
			}
		} 
		for (i=n;i>=1;i--)
		{
			for (j=1;j<=m;j++)
			{
				if (mp[i][j]=='F')
				up[i][j]=up[i+1][j]+1;
				else
					up[i][j]=0;
			}
		}
		for (i=n;i>=1;i--)
		{
			for (j=2;j<=m;j++)
			{
				if (up[i][j]<=up[i][j-1])
				ll[i][j]=ll[i][j-1]+1;
				else
					ll[i][j]=0;
			}
		}
		
		for (i=n;i>=1;i--)
		{
			for (j=m-1;j>=1;j--)
			{
				if (up[i][j]<=up[i][j+1])
				rr[i][j]=rr[i][j+1]+1;
				else
					rr[i][j]=0;
			}
		}
		 int maxx=0;
		for (i=1;i<=n;i++)
		{
			for (j=1;j<=m;j++)
			{
				int ret=up[i][j]*(1+ll[i][j]+rr[i][j]);
					if (ret>maxx) 
						maxx=ret;
			}
		}
		printf("%d\n",maxx*3);
	}	
	
	return 0;
	
}






n^3算法:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001; 

char mp[1005][1005];
int col[1005][1005];
int main()
{
	int n,s; 
	int t;
	cin>>t;
	while(t--)
	{
		memset(col,0,sizeof(col));
		int n,m;
		int i,j,k;
		cin>>n>>m;
		getchar();
		char sss[10];
		for (i=1;i<=n;i++)
		{
			for (j=1;j<=m;j++)
			{
				scanf("%s",sss);
				mp[i][j]=sss[0];
			}
		}
		int cnt=0;
		for (i=1;i<=n;i++)
		{
			for (j=1;j<=m;j++)
			{
				if (mp[i][j]=='R') continue;
				if (j==1) 
					col[i][j]=++cnt;
				if (mp[i][j]==mp[i][j-1])
					col[i][j]=col[i][j-1];
				else
					col[i][j]=++cnt;
			}
		}
		int maxx=0;
		for (i=1;i<=m;i++)
		{
			for (j=i;j<=m;j++)
			{
				int tmp=0;
				for (k=1;k<=n;k++)
				{
					if (!col[k][i]||!col[k][j]) 
					{tmp=0;continue;}
					if (col[k][i]==col[k][j])
					{
						tmp+=(j-i+1);
						if (tmp>maxx) 
							maxx=tmp;
					}
					else 
						tmp=0; 
				}
			} 
		}
		printf("%d\n",maxx*3);
			
		
		
	}	
	
	return 0;
	
}


你可能感兴趣的:(POJ1964/UVALive 3029 -City Game -求最大子矩形-(暴力枚举/dp))