【洛谷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; }