这道题和多米诺骨牌那道题很像
,都是涉及到差值的问题。
这道题是二维的,同时要取模.
这种题,因为当前的决策有后效性,会影响到差值,所以直接把
差值作为维度,然后计算答案的时候把差值为0的加起来就行了。
这里有两个人,所以可以多设一维第一人还是第二人,来回更新。
然后取模的时候记得+k再模k
#include<cstdio>
#include<algorithm>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
#define _for(i, a, b) for(int i = (a); i <= (b); i++)
#define cal(a, b) a = (a + b) % MOD //这句话省了巨多代码!!
using namespace std;
const int MAXN = 805;
const int MAXM = 16;
const int MOD = 1e9 + 7;
int f[MAXN][MAXN][MAXM][2];
int a[MAXN][MAXN], n, m, k, ans;
int main()
{
scanf("%d%d%d", &n, &m, &k); k++;
_for(i, 1, n)
_for(j, 1, m)
{
scanf("%d", &a[i][j]);
f[i][j][a[i][j]%k][0] = 1;
}
_for(i, 1, n)
_for(j, 1, m)
REP(h, 0, k)
{
cal(f[i][j][h][0], f[i-1][j][(h-a[i][j]+k)%k][1] + f[i][j-1][(h-a[i][j]+k)%k][1]);
cal(f[i][j][h][1], f[i-1][j][(h+a[i][j])%k][0] + f[i][j-1][(h+a[i][j])%k][0]);
if(h == 0) cal(ans, f[i][j][0][1]);
}
printf("%d\n", ans);
return 0;
}