题意
牛牛可以在n*m的图中向右走或者向下走,每个点有一个权值,经过某点获得该点权值并对1e4+7求模,问从(1,1)走到(n,m),在(n,m)点存在多少种权值情况。
题解
设一个dp三维布尔数组,dp[i][j][k]表示从(1,1)走到(i,j)点是否在(i,j)点可以产生k的权值。
易知转移方程
即当前位置只能由上面一格或左面一格转移而来,且若想权值可以为k,则转移前的权值需要为
code
#include <bits/stdc++.h>
#define reg register
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define eps 1e-8
#define pi acos(-1.0)
#define e exp(1.0)
#define ios ios::sync_with_stdio(false)
#define rep(i,l,r) for(int i=(l);i<(r);i++)
using namespace std;
const int maxn = 100 + 10;
const int mod = 1e4 + 7;
int n,m;
int v[maxn][maxn];
bool dp[105][105][10010];
int main()
{
cin>>n>>m;
for(int i = 1;i <= n;++i){
for(int j = 1;j <=m;++j){
cin>>v[i][j];
v[i][j] %= mod;
}
}
dp[1][1][v[1][1]] = 1;
for(int i = 1;i <= n;++i){
for(int j = 1;j <= m;++j){
for(int k = 0;k < mod;++k){
dp[i][j][k] |= dp[i-1][j][(k-v[i][j]+mod) % mod];
dp[i][j][k] |= dp[i][j-1][(k-v[i][j]+mod) % mod];
}
}
}
int res = 0;
for(int i = 0;i < mod;++i) res += dp[n][m][i];
printf("%d\n",res);
return 0;
} 
京公网安备 11010502036488号