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
  • 相关阅读:
    MS SQL Server备份与恢复实例
    如何加快查询,优化数据库
    使用索引的误区之一:没有使用复合索引的前导列导致查询不使用索引
    URL重写可删节日期模式正则表达式之强力应用
    索引全攻略
    大数据量分页存储过程效率测试附代码
    形成查询结果(实体框架) 使用导航属性导航关系
    C#开源资源大汇总
    大数据量的系统的数据库结构如何设计?
    数据库查询优化
  • 原文地址:https://www.cnblogs.com/mrclr/p/9536332.html
Copyright © 2011-2022 走看看