1.前言
我好弱啊,根本做不出啊~我开始怀疑我学了动规没......
首先瓶子容量要++,然后小a和uim是一起走的,只是轮流吸魔液而已。
2.解法
开一个数组f[i][j][k][p]表示在(i,j)格子处,二人魔液相差k,是第p个人吸。
那么uim吸魔液可以看成是小a扔掉一些魔液。bob表示瓶子容量,得到状态转移方程:
f[i][j][k][0]+=f[i-1][j][(bob+k-ma[i][j])%bob][1]+f[i][j-1][(bob+k-ma[i][j])%bob][1];
f[i][j][k][1]+=f[i-1][j][(k+ma[i][j])%bob][0]+f[i][j-1][(k+ma[i][j])%bob][0];
初始:f[i][j][ma[i][j]][0]=1。就是小a吸这个格子的魔液。
最后求所有f[i][j][0][1]的和即可。
注意常数优化。
3.代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<climits>
#include<iomanip>
#include<cmath>
#include<vector>
#include<algorithm>
using namespace std;
int read(){
int w=1,q=0;char ch=' ';
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')q=q*10+ch-'0',ch=getchar();
return w*q;
}
int n,m,bob,mod=1000000007;
int ma[805][805];
int f[805][805][17][2];
int main()
{
int i,j,k,ans=0,kl;
n=read();m=read();bob=read();bob++;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
ma[i][j]=read(),ma[i][j]=ma[i][j]%bob,f[i][j][ma[i][j]][0]=1;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
for(k=0;k<=bob;k++){
f[i][j][k][0]+=f[i-1][j][(bob+k-ma[i][j])%bob][1];
f[i][j][k][0]%=mod;
f[i][j][k][0]+=f[i][j-1][(bob+k-ma[i][j])%bob][1];
f[i][j][k][0]%=mod;
f[i][j][k][1]+=f[i-1][j][(ma[i][j]+k)%bob][0];
f[i][j][k][1]%=mod;
f[i][j][k][1]+=f[i][j-1][(ma[i][j]+k)%bob][0];
f[i][j][k][1]%=mod;
}
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)ans=(ans+f[i][j][0][1])%mod;
printf("%d",ans);
return 0;
}