$$ \text{设}f\left( n,m,k,d \right) \text{表示走到了格子}\left( n,m \right) \text{,} \\ \text{小}a\text{采集的魔液与}uim\text{采集的魔夜的差为}k\text{,这一步是小}a\text{还是}uim\text{采集的方案数} \\ \text{初始时,}f\left( n,m,mat_{n,m},1 \right) =\text{1\ }\left( \text{要求可以从任意点出发} \right) \\ \text{转移时} \\ f\left( n+\text{1,}m,k+mat_{n+\text{1,}m},0 \right) +=f\left( n,m,k,1 \right) \\ f\left( n,m+\text{1,}k+mat_{n,m+1},0 \right) +=f\left( n,m,k,1 \right) \\ f\left( n+\text{1,}m,k-mat_{n+\text{1,}m},1 \right) +=f\left( n,m,k,0 \right) \\ f\left( n,m+\text{1,}k-mat_{n,m+1},1 \right) +=f\left( n,m,k,0 \right) \\ \text{最后答案为所有}f\left( n,m,\text{0,}1 \right) \text{的和。} \\ $$
#include <iostream>
using int_t = int;
using std::cin;
using std::cout;
using std::endl;
const int_t mod = 1000000007;
int_t n, m, k;
//走到了n行m列,a与uim的差为k,最后一步0:a,1:uim的方案数
int_t f[802][802][16][2];
int_t mat[802][802];
inline void inc(int_t &x, int_t b)
{
x = ((x + b) % mod + mod) % mod;
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
k += 1;
for (int_t i = 1; i <= n; i++)
{
for (int_t j = 1; j <= m; j++)
{
scanf("%d", &mat[i][j]);
f[i][j][mat[i][j]][0] = 1;
}
}
int_t result = 0;
for (int_t i = 1; i <= n; i++)
{
for (int_t j = 1; j <= m; j++)
{
for (int_t k = 0; k < ::k; k++)
{
//下一步是a
inc(f[i + 1][j][(k + mat[i + 1][j]) % ::k][0], (f[i][j][k][1]));
inc(f[i][j + 1][(k + mat[i][j + 1]) % ::k][0], (f[i][j][k][1]));
//下一步是uim
inc(f[i + 1][j][(k - mat[i + 1][j] + ::k) % ::k][1], f[i][j][k][0]);
inc(f[i][j + 1][(k - mat[i][j + 1] + ::k) % ::k][1], f[i][j][k][0]);
}
inc(result, f[i][j][0][1]);
}
}
printf("%d", result);
return 0;
}
发表回复