zoukankan      html  css  js  c++  java
  • [ZJOI2008]生日聚会

    嘟嘟嘟

    此题一看就是一个dp题。

    首先我们设dp[i][j]表示前 i 个人中有 j 个男生(这和dp[i][j]表示 i 个男生 j 个女生等价),然而当我们转移到dp[i + 1][j + 1]或dp[i + 1][j]时,限制条件没有用上。所以要再加两维dp[i][j][x][y]表示前 i 个人中有 j 个男生,其中男生最多比女生多个,女生最多比男生多y个。

    这样很容易得出转移方程

        dp[i + 1][j + 1][x + 1][y - 1] += dp[i][j][x][y],

        dp[i + 1][j][x - 1][y + 1] += dp[i][j][x][y]

    但是当y或是x已经是0的时候,那还应该是0

        dp[i + 1][j + 1][x + 1][max(y - 1, 0)] += dp[i][j][x][y],

        dp[i + 1][j][max(x - 1, 0)][y + 1] += dp[i][j][x][y]

     还有一件事我也不太懂,就是为啥dp[i][j][x][y]要从右面转移,而不是有的状态转移到dp[i][j][x][y]……巨佬们求助啊

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<vector>
     8 #include<queue>
     9 #include<stack>
    10 #include<cctype>
    11 using namespace std;
    12 #define enter puts("")
    13 #define space putchar(' ')
    14 #define Mem(a) memset(a, 0, sizeof(a))
    15 typedef long long ll;
    16 typedef double db;
    17 const int INF = 0x3f3f3f3f;
    18 const db eps = 1e-8;
    19 const int maxn = 155;
    20 const int mod = 12345678;
    21 inline ll read()
    22 {
    23     ll ans = 0;
    24     char ch = getchar(), last = ' ';
    25     while(!isdigit(ch)) last = ch, ch = getchar();
    26     while(isdigit(ch)) ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
    27     if(last == '-') ans = -ans;
    28     return ans;
    29 }
    30 inline void write(ll x)
    31 { 
    32     if(x < 0) putchar('-'), x = -x;
    33     if(x >= 10) write(x / 10);
    34     putchar(x % 10 + '0');
    35 }
    36 
    37 int n, m ,k;
    38 int dp[maxn << 1][maxn][21][21], ans = 0;
    39 
    40 int main()
    41 {
    42     n = read(); m = read(); k = read();
    43     dp[0][0][0][0] = 1;
    44     for(int i = 0; i < n + m; ++i)
    45         for(int j = 0; j <= n; ++j)
    46             for(int x = 0; x <= k; ++x)
    47                 for(int y = 0; y <= k; ++y)
    48                 {
    49                     if(!dp[i][j][x][y]) continue;
    50                     if(j + 1 <= n && x + 1 <= k) dp[i + 1][j + 1][x + 1][max(y - 1, 0)] += dp[i][j][x][y] %= mod;
    51                     if(y + 1 <= k) dp[i + 1][j][max(x - 1, 0)][y + 1] += dp[i][j][x][y] %= mod;
    52                 }
    53     for(int i = 0; i <= k; ++i)    
    54         for(int j = 0; j <= k; ++j)
    55         ans = (ans + dp[n + m][n][i][j]) % mod;
    56     write(ans);
    57     return 0;
    58 }
    View Code
  • 相关阅读:
    Codechef EDGEST 树套树 树状数组 线段树 LCA 卡常
    BZOJ4319 cerc2008 Suffix reconstruction 字符串 SA
    Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal
    Codeforces 316G3 Good Substrings 字符串 SAM
    Codechef CHSIGN Change the Signs(May Challenge 2018) 动态规划
    BZOJ1396 识别子串 字符串 SAM 线段树
    CodeForces 516C Drazil and Park 线段树
    CodeForces 516B Drazil and Tiles 其他
    CodeForces 516A Drazil and Factorial 动态规划
    SPOJ LCS2
  • 原文地址:https://www.cnblogs.com/mrclr/p/9536332.html
Copyright © 2011-2022 走看看