洛谷P1373 小a和uim之大逃离【线性dp】

题目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 } 
原文地址:https://www.cnblogs.com/wyboooo/p/10963203.html