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('\n')
 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;}

 

posted @ 2015-07-22 12:45  AI_Believer  阅读(209)  评论(0编辑  收藏  举报