LA -- 3029 City Game 【思维 + dp】

来源:互联网 发布:全自动猫厕所 知乎 编辑:程序博客网 时间:2024/06/14 09:45

传送门
//题意: 给出一个只有F,R组成的矩阵, 找出一个最大全由F组成的矩阵, 并将它的面积乘3输出.
//思路: 还是类似于扫描法, 维护几个值, up[i][j]代表格子i,j 往上最大能走的空格数. left[i][j]代表格子i,j 往左最大能走的空格数. right[i][j]代表格子i,j 往右最大能走的空格数. 那么怎么计算了. 如果第i行第j列不是空格, 那么三个数组的值都为0. 否则up[i][j] = up[i-1][j] + 1. left[i][j] = max(left[i-1][j], lo + 1), lo 代表是第i行第j列左边的最近障碍格的列编号. right[i]][j] = min(right[i-1][j], ro - 1), ro的含义和lo类似. 取min, max就是根据它形成的矩形来说的. 那么我们事先从左到右维护好left和up, 再从右到左维护right, 顺便更新答案.

AC Code

/** @Cain*/const int maxn=1e3+5;int cas=1;int mapp[maxn][maxn;   // !!!int up[maxn][maxn],l[maxn][maxn],r[maxn][maxn];void solve(){    int n,m; Fill(up,0); Fill(l,0); Fill(r,0);    scanf("%d%d",&n,&m);    for(int i=1;i<=n;i++){        for(int j=1;j<=m;j++){            char s[10] = {0};            scanf("%s",s);            mapp[i][j] = s[0] == 'F'?1:-1;            //转化为数字矩阵.        }    }    int res = 0;    for(int i=1;i<=n;i++){        int lo=0;        for(int j=1;j<=m;j++){            if(mapp[i][j] == -1) {                up[i][j] = l[i][j] = 0;                lo = j;            }            else {                up[i][j] = up[i-1][j] + 1;                l[i][j] = max(l[i-1][j],lo+1);            }        }        int ro = m+1;        for(int j=m;j>=1;j--){            if(mapp[i][j] == -1) {                r[i][j] = m+1;  //right取0的真实含义是不能取它, 因为我们取的min                //所以就把它的值设为最大, 那么就不会取到它了.                ro = j;            }            else {                r[i][j] = i==1?ro-1:min(r[i-1][j],ro-1);                res = max(res,up[i][j] * (r[i][j]-l[i][j]+1));                //更新答案.            }        }    }    printf("%d\n",res*3);}
原创粉丝点击