【洛谷P1373】小a和uim之大逃离

小a和uim之大逃离

题目链接

因为每次只能向下或向右走,我们可以递推

dp[i][j][d][0/1]表示走到(i,j),mod k 意义下差值为d,轮到小a/小uim操作时的方案数

dp[i][j][d][0]=dp[i-1][j][(d-a[i][j]+k)%k][1]+dp[i][j-1][(d-a[i][j]+k)%k][1];

dp[i][j][d][1]=dp[i-1][j][(d+a[i][j])%k][0]+dp[i][j-1][(d+a[i][j])%k][0];

 

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MOD 1000000007
#define N 810
int n,m,k,f[N][N][20][2],ans;
inline int read(){
    int x=0; char c=getchar();
    while(c<'0'||c>'9') c=getchar();
    while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
    return x;
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    k++; int x;
    for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++){
         x=read(); x%=k;
        f[i][j][x][0]=1;
         for(int d=0;d<k;d++){
             int &d0=f[i][j][d][0];
             int &d1=f[i][j][d][1];
             int ld0=(d+k-x)%k;
             int ld1=(d+x)%k;
            d0=(d0+f[i-1][j][ld0][1])%MOD;
            d0=(d0+f[i][j-1][ld0][1])%MOD;
            d1=(d1+f[i-1][j][ld1][0])%MOD;
            d1=(d1+f[i][j-1][ld1][0])%MOD;
         }
         ans=(ans+f[i][j][0][1])%MOD;
     }
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2018-08-03 19:12  yjk  阅读(99)  评论(0编辑  收藏  举报