• bzoj 1037[ZJOI2008]生日聚会Party


    1037: [ZJOI2008]生日聚会Party

    Time Limit: 10 Sec  Memory Limit: 162 MB

    Description

      今天是hidadz小朋友的生日,她邀请了许多朋友来参加她的生日party。 hidadz带着朋友们来到花园中,打算
    坐成一排玩游戏。为了游戏不至于无聊,就座的方案应满足如下条件:对于任意连续的一段,男孩与女孩的数目之
    差不超过k。很快,小朋友便找到了一种方案坐了下来开始游戏。hidadz的好朋友Susie发现,这样的就座方案其实
    是很多的,所以大家很快就找到了一种,那么到底有多少种呢?热爱数学的hidadz和她的朋友们开始思考这个问题
    …… 假设参加party的人中共有n个男孩与m个女孩,你是否能解答Susie和hidadz的疑问呢?由于这个数目可能很
    多,他们只想知道这个数目除以12345678的余数。

    Input

      仅包含一行共3个整数,分别为男孩数目n,女孩数目m,常数k。

    Output

      应包含一行,为题中要求的答案。

    Sample Input

    1 2 1

    Sample Output

    1

    HINT

    n , m ≤ 150,k ≤ 20。

    开始yy了一个三维的dp,于是就gg了,然后想到了4维的方法

    我们用 f[i][j][k1][k2] 表示当前放到第i个位置一共放了j个男生并且序列结尾最大的男生减女生的数量差有 k1个, 女生减男生的差有k2个

    这样能写出转移方程

    放男生 :

    f[i][j][k1][k2] += f[i - 1][j - 1][k1 - 1][k2 + 1]

    放女生 :

    f[i][j][k1][k2] += f[i - 1][j][k1 + 1][k2 - 1]

    注意当 k1 = 0 时, 放女生不会改变k1 所以:

    f[i][j][0][k2] += f[i - 1][j][0][k2 - 1]

    k2 = 0时同理

    f[i][j][k1][0] += f[i - 1][j - 1][k1 - 1][0]

    开始空间算错了还以为要滚动 2333

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #define LL long long
     6 
     7 using namespace std;
     8 
     9 LL mod = 12345678;
    10 int n, m, K;
    11 int now = 1;
    12 LL ans = 0;
    13 LL f[2][160][22][22];
    14 inline LL read()
    15 {
    16     LL x = 0, w = 1; char ch = 0;
    17     while(ch < '0' || ch > '9') {
    18         if(ch == '-') {
    19             w = -1;
    20         }
    21         ch = getchar();
    22     }
    23     while(ch >= '0' && ch <= '9') {
    24         x = x * 10 + ch - '0';
    25         ch = getchar();
    26     }
    27     return x * w;
    28 }
    29 
    30 int main()
    31 { 
    32     n = read(), m = read(), K = read();
    33     f[0][0][0][0] = 1;
    34     for(int i = 1; i <= n + m; i++) {
    35         memset(f[now], 0, sizeof f[now]);
    36         for(int j = 0; j <= n; j++) {
    37             for(int k1 = 0; k1 <= K; k1++) {
    38                 for(int k2 = 0; k2 <= K; k2++) {
    39                 /*if(j > 0) {
    40                     f[i][j][k] += f[i - 1][j - 1][k - 1] % mod;
    41                 }
    42                 f[i][j][k] = (f[i][j][k] + f[i - 1][j][k + 1]) % mod;*/
    43                     if(k2 != 0) {
    44                         f[now][j][k1][k2] = (f[now][j][k1][k2] + f[now ^ 1][j][k1 + 1][k2 - 1]) % mod;
    45                         if(k1 == 0) {
    46                             f[now][j][0][k2] = (f[now][j][0][k2] + f[now ^ 1][j][0][k2 - 1]) % mod;
    47                         }
    48                     } 
    49                     if(k1 != 0 && j != 0) {
    50                         f[now][j][k1][k2] = (f[now][j][k1][k2] + f[now ^ 1][j - 1][k1 - 1][k2 + 1]) % mod;
    51                         if(k2 == 0) {
    52                             f[now][j][k1][0] = (f[now][j][k1][0] + f[now ^ 1][j - 1][k1 - 1][0]) % mod;
    53                         }
    54                     }
    55                 }
    56             }
    57         }
    58         now = now ^ 1;
    59     }
    60 /*    for(int i = 1; i <= n + m; i++) {
    61         cout<<i<<endl;
    62         for(int j = 0; j <= n; j++) {
    63             for(int k = 30 - K; k <= 30 + K; k++) {
    64                 cout<<f[i][j][k]<<" ";
    65             }
    66             cout<<endl;
    67         }
    68         cout<<endl<<endl;
    69     }*/
    70     /*for(int i = 1; i <= n + m; i++) {
    71         for(int j = 0; j <= n; j++) {
    72             for(int k1 = 0; k1 <= K; k1++) {
    73                 for(int k2 = 0; k2 <= K; k2++) {
    74                     cout<<f[i][j][k1][k2]<<" ";
    75                 }
    76                 cout<<endl;
    77             }
    78             cout<<endl;
    79         }
    80         cout<<endl<<endl;
    81     }*/
    82     for(int k1 = 0; k1 <= K; k1++) {
    83         for(int k2 = 0; k2 <= K; k2++) {
    84             ans = (ans + f[now ^ 1][n][k1][k2]) % mod;
    85         }
    86     }
    87     printf("%lld
    ", ans);
    88     return 0;
    89 }
    90 
    91 /*
    92 
    93 1 2 1
    94 */
    View Code
  • 相关阅读:
    怎么把共享文件夹显示在我的电脑
    window时间同步机制的简单介绍
    向指定服务器的指定端口发送UDP包
    窜口通信-读取时间码
    窜口通信-发送时间码
    回环网卡通信
    简单的TCP接受在转发到客户端的套接口
    国内能用的NTP服务器及和标准源的偏差值
    简单的UDP接受程序
    TCP包服务器接受程序
  • 原文地址:https://www.cnblogs.com/wuenze/p/8479288.html
Copyright © 2020-2023  润新知