一道比较好的dp题。
可以以任一节点为起点。以任意节点为终点。然后是转移是有方向的。
然后我们在处理初始状态时,就不能只处理一个,应该站在全局角度中思考。
然后对于所有能影响结果都都应记录
但如果记录两人分别的魔液的数量,显然空间是不够的。这道题是让我们求解相等时的情况,我们应该讲注意力放在差上
这样,不仅节约了一维,也使统计次数更叫方便
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int f[801][801][17][2];//f[i][j][k][0/1]表示在(i,j)时,差为k,谁已经行动完(1:小a 0:uim)
int map[801][801];
const int mod=1e9+7;
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
k++;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&map[i][j]);
f[i][j][map[i][j]%=k][1]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
for(int l=0;l<=k;l++)
{
f[i][j][l][0]=(f[i][j][l][0]+f[i-1][j][(l+map[i][j]+2*k)%k][1])%mod;//枚举差,并转移
f[i][j][l][0]=(f[i][j][l][0]+f[i][j-1][(l+map[i][j]+2*k)%k][1])%mod;
f[i][j][l][1]=(f[i][j][l][1]+f[i-1][j][(l-map[i][j]+2*k)%k][0])%mod;
f[i][j][l][1]=(f[i][j][l][1]+f[i][j-1][(l-map[i][j]+2*k)%k][0])%mod;
}
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) ans=(ans+f[i][j][0][0])%mod;//这里也可以填写f[i][j][k][0],具体为什么,可以思考思考qwq
printf("%d",ans);
}