标签:
题意:
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; }
标签:
原文地址:http://www.cnblogs.com/fish7/p/4230017.html