Codeforces 1247E. Rock Is Push


傳送門

顯然考慮 $dp$ ,設 $fx[i][j]$ 表示從 $(i,j)$ 出發往下走一格,最終到達 $(n,m)$ 的方案數,$fy[i][j]$ 表示從 $(i,j)$ 出發往右走一格,最終到達 $(n,m)$ 的方案數

如果 $(i,j)$ 本身有石頭就把這個石頭忽略

那么對於 $fx[i][j]$ ,如果 $(i+1,j)$ 沒有石頭,轉移為 $fx[i][j]=fx[i+1][j]+fy[i+1][j]$

如果 $(i+1,j)$ 有石頭,因為 $fx[i+1][j]$ 沒有算到本身的石頭,所以方案中多出了一類往下走到 $(x,y)$ 再往右的方案

但是因為這個石頭的存在,我們最多只能走到 $(x-1,y)$ ,那么方案便多出了 $fy[x][y]$ ,再減去即可,顯然 $x,y$ 可以通過預處理每列的前綴石頭數得到

然后對於 $fy$ 也差不多轉移,所以就做完了

記得特判 $(n,m)=(1,1)$ 的情況

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
    return x*f;
}
const int N=2007,mo=1e9+7;
inline int fk(int x) { return x>=mo ? x-mo : x; }
int n,m,ans;
int cntx[N][N],cnty[N][N];
int fx[N][N],fy[N][N];
char s[N][N];
int main()
{
    n=read(),m=read();
    for(int i=1;i<=n;i++)
        scanf("%s",s[i]+1);
    for(int i=n;i>=1;i--)
        for(int j=m;j>=1;j--)
        {
            cntx[i][j]=cntx[i+1][j]+(s[i][j]=='R');
            cnty[i][j]=cnty[i][j+1]+(s[i][j]=='R');
        }
    for(int i=1;i<m;i++)
        if(!cnty[n][i]) fy[n][i]=1;
    for(int i=1;i<n;i++)
        if(!cntx[i][m]) fx[i][m]=1;
    for(int i=n-1;i;i--)
        for(int j=m-1;j;j--)
        {
            fx[i][j]=fk(fx[i+1][j]+fy[i+1][j]);
            if(s[i+1][j]=='R') fx[i][j]=fk(fx[i][j]- fy[ n-cntx[i+1][j]+1 ][j] +mo);
            fy[i][j]=fk(fx[i][j+1]+fy[i][j+1]);
            if(s[i][j+1]=='R') fy[i][j]=fk(fy[i][j]- fx[i][ m-cnty[i][j+1]+1 ] +mo);
        }
    if(n==1&&m==1&&s[1][1]=='.') ans=1;
    else ans=fk(fx[1][1]+fy[1][1]);
    printf("%d\n",ans);
    return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM