您的位置:首页 > 其它

hdu 1505 City Game(DP)

2015-01-17 00:23 435 查看
题意:

M*N的格子构成的城市,每一个格子上不是F就是R,F代表Free,表示这个格子可以使用,R代表不可以使用。

要求:在这里面找到一个矩形,使得面积是最大的。(即必须满足覆盖矩形的每一个格子都是F)

输入:

M,N<=1000

思路:

刚开始一个思路是如果是F设成1,如果是R设成-INF。然后求最大子矩阵(最大子段和的扩展)

可是最大子矩阵的算法貌似是O(N^3)的,所以不行,,

换个思路,假设现在有一个面积,它是最大的,它有特点:向左没法延伸,向右没法延伸,向上没办法,向下也没法办。

我们不考虑向下,枚举每一层假设其这个面积的底。然后,,,然后,,这不就是柱状图求最大面积那道题了么,,那道题时间复杂度应该是介于O(n)和O(n^2)的,

俺把其看成O(C*n) C是常数,,,

看代码,,。

代码:

int m,n;
int a[1005][1005];
int leftt[1005], rightt[1005];

int proc(int x){ // row x
rep(i,1,n) leftt[i]=rightt[i]=i;

rep(i,2,n){
if(a[x][i]<=a[x][i-1]){
leftt[i] = leftt[i-1];
while(leftt[i]-1 >0 && a[x][i]<=a[x][leftt[i]-1]){
leftt[i] = leftt[leftt[i]-1];
}
}
}

rep2(i,n-1,1){
if(a[x][i]<=a[x][i+1]){
rightt[i] = rightt[i+1];
while(rightt[i]+1<=n && a[x][i]<=a[x][rightt[i]+1]){
rightt[i] = rightt[rightt[i]+1];
}
}
}

int ans = 0;
rep(i,1,n){
ans = max( ans,(rightt[i]-leftt[i]+1)*a[x][i] );
}
return ans;

}

int main(){

int T;
cin>>T;
while(T--){
scanf("%d%d",&m,&n);
rep(i,1,m) rep(j,1,n){
char kind[3];
scanf("%s",&kind);
if(kind[0]=='R') a[i][j]=0; else a[i][j]=1;
}
rep(i,2,m) rep(j,1,n){
if(a[i][j]==0) continue;
if(a[i-1][j]>0) a[i][j] += a[i-1][j];
}

int ans = 0;
rep(i,1,m){
ans = max( ans,3*proc(i) );
}

printf("%d\n",ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: