bzoj [ZJOI2008]生日聚会Party

思路:dp, 用dp[ i ][ j ][ u ][ v ] 表示, 有n个人,其中有j个是男生,后缀区间中男生人数减去女生人数的最大值为u, 女生人数减去男生人数

的最大值为v, 然后就能写出状态转移方程。

 1 #include<bits/stdc++.h>
 2 #define LL long long
 3 #define fi first
 4 #define se second
 5 #define mk make_pair
 6 #define pii pair<int,int>
 7 #define piii pair<int, pair<int,int>>
 8  
 9 using namespace std;
10  
11 const int N = 200 + 7;
12 const int M = 1e4 + 7;
13 const int inf = 0x3f3f3f3f;
14 const LL INF = 0x3f3f3f3f3f3f3f3f;
15 const int mod = 12345678;
16  
17 int n, m, k;
18 int dp[307][157][21][21];
19 int main() {
20     scanf("%d%d%d", &n, &m, &k);
21     dp[0][0][0][0] = 1;
22  
23     for(int i = 0; i < n + m; i++) {
24         for(int j = 0; j <= n; j++) {
25             for(int u = 0; u <= k; u++) {
26                 for(int v = 0; v <= k; v++) {
27                     if(dp[i][j][u][v]) {
28                         if(u + 1 <= k && j + 1 <= n) {
29                             dp[i + 1][j + 1][u + 1][max(v - 1, 0)] += dp[i][j][u][v];
30                             dp[i + 1][j + 1][u + 1][max(v - 1, 0)] %= mod;
31                         }
32  
33                         if(v + 1 <= k && i + 1 - j <= m) {
34                             dp[i + 1][j][max(u - 1, 0)][v + 1] += dp[i][j][u][v];
35                             dp[i + 1][j][max(u - 1, 0)][v + 1] %= mod;
36                         }
37                     }
38                 }
39             }
40         }
41     }
42  
43     LL ans = 0;
44     for(int i = 0; i <= k; i++)
45         for(int j = 0; j <= k; j++)
46             ans = (ans + dp[n + m][n][i][j]) % mod;
47     printf("%lld\n", ans);
48     return 0;
49 }
50 /*
51  
52  
53 */

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/9058428.html