Luogu1373 小a和uim之大逃离

$$ \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;
}

 

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理