HDU 1505 & POJ 1964 City Game (递推+扫描法)
2013-08-15 19:01
260 查看
题意:一个矩阵,有些格子是F,有些是R,要你找到最大的子矩阵使得矩阵内全是F
思路:直接枚举每个子矩阵,显然复杂度是O(m^3 n^3),显然TLE。
我们可以使用扫描法:用up(i,j)表示格子(i,j)悬垂线(悬垂线就是指这个格子往上走遇到第一个R的格子之前的线段)的长度。left(i,j)表示悬垂线往左扫最左能移动到的位置(遇到R会停止),right(i,j)表示悬垂线往右扫最右能移动到的位置(遇到R会停止)。那么格子(i,j)可以对应一个这样的最大F矩形:以第i行作为底边,第i-up(i,j)+1行作为上底边,left(i,j)所在列为左边,right(i,j)所在列作为右边的矩形。
那么最终答案就是每个格子对应的矩形中的最大值。
up(i,j)可以用递推式:(1)若map[i][j]=='F',up(i,j)=up(i-1,j)+1 (2)若map[i][j]=='R',up(i,j)=0
left(i,j)可以用递推式:(1)若map[i][j]=='F',left(i,j)=max{left(i-1,j),lo+1} (lo是格子(i,j)左边最近的'R'的列)(2)若map[i][j]=='R',left(i,j)=0
right(i,j)可以用递推式:(1)若map[i][j]=='F',right(i,j)=max{right(i-1,j),ro-1} (ro是格子(i,j)右边最近的'R'的列)(2)若map[i][j]=='R',right(i,j)=n
注意:这个题目读入数据规模较大,用scanf会TLE。。。。getchar()才行。。。
思路:直接枚举每个子矩阵,显然复杂度是O(m^3 n^3),显然TLE。
我们可以使用扫描法:用up(i,j)表示格子(i,j)悬垂线(悬垂线就是指这个格子往上走遇到第一个R的格子之前的线段)的长度。left(i,j)表示悬垂线往左扫最左能移动到的位置(遇到R会停止),right(i,j)表示悬垂线往右扫最右能移动到的位置(遇到R会停止)。那么格子(i,j)可以对应一个这样的最大F矩形:以第i行作为底边,第i-up(i,j)+1行作为上底边,left(i,j)所在列为左边,right(i,j)所在列作为右边的矩形。
那么最终答案就是每个格子对应的矩形中的最大值。
up(i,j)可以用递推式:(1)若map[i][j]=='F',up(i,j)=up(i-1,j)+1 (2)若map[i][j]=='R',up(i,j)=0
left(i,j)可以用递推式:(1)若map[i][j]=='F',left(i,j)=max{left(i-1,j),lo+1} (lo是格子(i,j)左边最近的'R'的列)(2)若map[i][j]=='R',left(i,j)=0
right(i,j)可以用递推式:(1)若map[i][j]=='F',right(i,j)=max{right(i-1,j),ro-1} (ro是格子(i,j)右边最近的'R'的列)(2)若map[i][j]=='R',right(i,j)=n
注意:这个题目读入数据规模较大,用scanf会TLE。。。。getchar()才行。。。
#include<cstdio> #include<iostream> #define MAXN 1005 using namespace std; int T,n,m,righ[MAXN][MAXN],up[MAXN][MAXN],lef[MAXN][MAXN]; char map[MAXN][MAXN]; int main() { scanf("%d",&T); while(T--) { int ans=0; scanf("%d%d",&m,&n); getchar(); for(int i=0;i<m;++i) for(int j=0;j<n;++j) { char ch=getchar(); while(ch!='F' && ch!='R') ch=getchar();//处理读入,注意用while,直到读入为F或者R为止 map[i][j]=ch; } for(int j=0;j<n;++j) for(int i=0;i<m;++i) if(map[i][j]=='R') up[i][j]=0; else up[i][j]=i? up[i-1][j]+1:1;//递推up(i,j) for(int i=0;i<m;++i) for(int j=0,lo=-1;j<n;++j) if(map[i][j]=='R') lo=j,lef[i][j]=0; else lef[i][j]=i? max(lo+1,lef[i-1][j]):lo+1;//递推left(i,j) for(int i=0;i<m;++i) for(int j=n-1,ro=n;j>=0;--j) if(map[i][j]=='R') ro=j,righ[i][j]=n; else righ[i][j]=i? min(ro-1,righ[i-1][j]):ro-1;//递推right(i,j) for(int i=0;i<m;++i) for(int j=0;j<n;++j) if(map[i][j]=='F') ans=max(ans,(righ[i][j]-lef[i][j]+1)*up[i][j]);//计算答案取最大值 printf("%d\n",ans*3); } return 0; }
相关文章推荐
- HDU 1505 & POJ 1964 City Game (递推+扫描法)
- POJ 1964&HDU 1505&HOJ 1644 City Game(最大0,1子矩阵和总结)
- HDU 1505 Largest Rectangle in a Histogram && HDU 1506 City Game(动态规划)
- HDU 1506&1505 - Largest Rectangle in a Histogram & City Game
- HDU 1505 Largest Rectangle in a Histogram && HDU 1506 City Game(动态规划)
- HDU&POJ训练记录3 二分图KM算法
- HDU 1505 City Game(DP)
- HDU 1325&&POJ 1308 Is It A Tree? 并查集判断能否树(能否形成环)
- HDU 1116 && UVA 10129 && POJ 1386 ------ Play on Words(欧拉路径 + 并查集)
- HDU 1159 && POJ 1458
- poj 1177 & hdu 1828 Picture(线段树+离散化)
- POJ 1008 && HDU 1444 Maya Calendar(历法)
- hdu1505 City Game (最大子矩形)
- HDU 1505 City Game
- POJ 3344 & HDU 2414 Chessboard Dance(模拟)
- POJ 2208 Pyramids && HDU 1141 校庆神秘建筑 (欧拉四面体公式)
- HDU 2732&&POJ 2711 Leapin' Lizards 【最大流Dinic】
- POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
- POJ 1458 & HDU 1159 - Common Subsequence(最长公共子序列)
- POJ 3004 && HDU 1922 Subway planning