• BZOJ 1037 [ZJOI2008]生日聚会Party


    1037: [ZJOI2008]生日聚会Party

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1583  Solved: 936
    [Submit][Status][Discuss]

    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

    对于100%的数据, n , m ≤ 150,k ≤ 20。

    Source

    题解:一眼DP,不过状态好像挺难想的。。。

    设dp[i][j][k1][k2]表示前i个人中,有j个男孩,男孩最多比女孩多k1个,女孩最多比男孩多k2个的最大方案数。。。

    然后分男孩女孩转移

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 using namespace std;
    10 const int maxn=20+5,maxm=150+10;
    11 int n,m,k,dp[2][maxm][maxn][maxn];
    12 int mod=12345678;
    13 inline int read(){
    14     int x=0,sig=1;char ch=getchar();
    15     for(;!isdigit(ch);ch=getchar())if(ch=='-')sig=0;
    16     for(;isdigit(ch);ch=getchar())x=10*x+ch-'0';
    17     return sig?x:-x;
    18 }
    19 inline void write(int x){
    20     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    21     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    22     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    23 }
    24 void init(){
    25     n=read();m=read();k=read();
    26     int tp=0;dp[0][0][0][0]=1;
    27     for(int i=0;i<n+m;i++){
    28         tp^=1;
    29         memset(dp[tp],0,sizeof(dp[tp]));
    30         for(int j=0;j<=min(i,n);j++)
    31             for(int k1=0;k1<=min(j,k);k1++)
    32                 for(int k2=0;k2<=min(i-j,k);k2++){
    33                    if(k1<k&&j<n)(dp[tp][j+1][k1+1][max(k2-1,0)]%=mod)+=(dp[tp^1][j][k1][k2]%=mod);
    34                    if(k2<k&&i-j<m)(dp[tp][j][max(k1-1,0)][k2+1]%=mod)+=(dp[tp^1][j][k1][k2]%=mod);
    35                 }
    36     }
    37     int ans=0;
    38     for(int k1=0;k1<=k;k1++)
    39         for(int k2=0;k2<=k;k2++)
    40             (ans+=(dp[tp][n][k1][k2]%=mod))%=mod;
    41    write(ans);
    42     return;
    43 }
    44 void work(){
    45     return;
    46 }
    47 void print(){
    48     return;
    49 }
    50 int main(){init();work();print();return 0;}
  • 相关阅读:
    小学二年级四则运算软件需求规格说明书
    周活动总结
    构建之法阅读笔记01
    学习进度条01
    四则运算
    软件工程概论
    课后作业1
    继承与多态-课后作业
    python文件处理-将图像根据坐标画矩形标记
    python文件处理-将图像根据坐标切割成若干小图
  • 原文地址:https://www.cnblogs.com/chxer/p/4667059.html
Copyright © 2020-2023  润新知