题目:https://www.luogu.org/problemnew/show/P1373
题意:
有一个n*m的地图,每个点上有一个数值。两个人在任一点开始任一点结束,只能往右或往下走,轮流收集数值。
超过k+1时会清零。问使得他们最后收集到的数值相等的方案数。
思路:
每次状态数一多再牵扯到方案数就开始懵。其实这道题也不怎么难。
$dp[i][j][h][0]$表示走到$(i,j)$,差值是$h$且最后一步是小a时的方案数。
1 //#include<bits/stdc++> 2 #include<stdio.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstring> 6 #include<stdlib.h> 7 #include<queue> 8 #include<map> 9 #include<stack> 10 #include<set> 11 12 #define LL __int128 13 #define ull unsigned long long 14 #define inf 0x7f7f7f7f 15 16 using namespace std; 17 18 int n, m, k; 19 const int maxn = 805; 20 const int mod = 1e9+7; 21 int num[maxn][maxn]; 22 int dp[maxn][maxn][20][2]; 23 24 int main() 25 { 26 scanf("%d%d%d", &n, &m, &k);k++; 27 for(int i = 1; i <= n; i++){ 28 for(int j = 1; j <= m; j++){ 29 scanf("%d", &num[i][j]); 30 dp[i][j][num[i][j] % k][0] = 1; 31 } 32 } 33 34 35 for(int i = 1; i <= n; i++){ 36 for(int j = 1; j <= m; j++){ 37 for(int h = 0; h <= k; h++){ 38 dp[i][j][h][0] = (dp[i][j][h][0] + dp[i][j - 1][(h - num[i][j] + k) % k][1]) % mod; 39 dp[i][j][h][0] = (dp[i][j][h][0] + dp[i - 1][j][(h - num[i][j] + k) % k][1]) % mod; 40 dp[i][j][h][1] = (dp[i][j][h][1] + dp[i][j - 1][(h + num[i][j]) % k][0]) % mod; 41 dp[i][j][h][1] = (dp[i][j][h][1] + dp[i - 1][j][(h + num[i][j]) % k][0]) % mod; 42 } 43 } 44 } 45 46 int ans = 0; 47 for(int i = 1; i <= n; i++){ 48 for(int j = 1; j <= m; j++){ 49 ans = (ans + dp[i][j][0][1]) % mod; 50 } 51 } 52 printf("%d ", ans); 53 return 0; 54 }