UVALive 3029 City Game (扫描维护)

http://acm.hust.edu.cn/vjudge/contest/131137#problem/B

题解:
是按照大白书来做的,自己确实没有想到很好的解法。
感觉这种递推关系很奇妙。
大白书的解法是使用了三个数组维护了这个矩阵的信息。
Left[i][j]表示(i,j)点左边最近的障碍位置+1,也就是F矩阵向左最左边可延伸的位置。
Right[i][j]表示(i,j)右边最近的障碍位置-1,也就是F矩阵向右左右边可延伸的位置。
up[i][j]表示(i,j)位置向上最上方可延伸的位置。
对于每一个(i,j)来说,ans=max(ans,(Right[i][j]-Left[i][j]+1)*up[i][j]);
这个ans值就会是最大的,大家可以仔细想一下,左边可以延伸最大了,右边最大了,上面也是延伸的最大的,那毫无疑问当前位置可以扩展得到的F矩阵就是最大的了。
把每一个矩阵都维护一遍就可以得到答案了。
这个递推的关系还是很巧妙的。
Left[i][j]=(i==0?lclose+1:max(Left[i-1][j],lclose+1));
这一句,我们扩展左边的,肯定是通过Left[i-1][j]来得到的,lclose表示左边最近的障碍在哪里?然后加上1就行了。
Right[i][j]也是同理得到的。

#include
using namespace std;

const int maxn=1e3+5;
char a[maxn][maxn];

int Left[maxn][maxn],Right[maxn][maxn],up[maxn][maxn];

int main() {
#ifdef tangge
    freopen("LA3029.in","r",stdin);
#endif // tangge
    int T,n,m;
    scanf("%d",&T);
    while(T--) {
        scanf("%d%d",&n,&m);
        char Tch;
        for(int i=0; i
            for(int j=0; j
                while((Tch=getchar())&&(Tch!='F'&&Tch!='R')) {}
                a[i][j]=Tch;
            }
        }
        int ans=0;
        for(int i=0; i
            int lclose=-1,rclose=m;
            for(int j=0; j
                if(a[i][j]=='R') {
                    up[i][j]=Left[i][j]=0,lclose=j;
                } else {
                    Left[i][j]=(i==0?lclose+1:max(Left[i-1][j],lclose+1));
                    up[i][j]=(i==0?1:up[i-1][j]+1);
                }
            }
            for(int j=m-1; j>=0; --j) {
                if(a[i][j]!='R') {
                    Right[i][j]=(i==0?rclose-1:min(Right[i-1][j],rclose-1));
                    ans=max(ans,(Right[i][j]-Left[i][j]+1)*up[i][j]);
                } else rclose=j,Right[i][j]=m-1;
            }
        }
        printf("%d\n",ans*3);
    }
    return 0;
}

你可能感兴趣的:(UVALive 3029 City Game (扫描维护))