1037: [ZJOI2008]生日聚会Party

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。

 

用F[i][j][k1][k2]表示前i个人中有j个男生,其中男生最多比女生k1个,女生最多比男生多k2个

然后对于第i+1个人,有两种情况:

1.当他是男生时:F[i+1][j+1][k1+1][k2-1]+=F[i][j][k1][k2](注意:当k2-1<0时k2-1=0)

2.当他是女生时:F[i+1][j][k1-1][k2+1]+=F[i][j][k1][k2]

然后就可以做了。。。

然后我们可以发现这道题的表示前i个人的状态每次只涉及到i和i+1然后可以考虑滚动数组,然后去掉这个状态,就可以省内存了。。。

不过我并没有用。。。=,=

 4 #include<iostream>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<cstring>
 8 #include<cstdio>
 9 #include<algorithm>
10 #include<string>
11 #include<map>
12 #include<queue>
13 #include<vector>
14 #include<set>
15 #define inf 1000000000
16 #define eps 1e-10
17 #define mod 12345678
18 #define maxn 150+5
19 #define maxm 20+5
20 #define ll long long
21 #define for0(i,n) for(int i=0;i<=(n);i++)
22 #define for1(i,n) for(int i=1;i<=(n);i++)
23 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
24 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
25 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
26 using namespace std;
27 int f[310][maxn][maxm][maxm];
28 int read(){
29     int x=0,f=1;char ch=getchar();
30     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
31     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
32     return x*f;
33 }
34 int main(){
35     //freopen("input.txt","r",stdin);
36     //freopen("output.txt","w",stdout);
37     int n=read(),m=read(),k=read();
38     f[0][0][0][0]=1;
39     for0(i,n+m)                
40         for0(j,min(i,n))
41             for0(k1,min(min(i,j),k))
42                 for0(k2,min(min(i,i-j),k)){
43                     if(k1<k&&j<n)f[i+1][j+1][k1+1][max(k2-1,0)]=(f[i][j][k1][k2]+f[i+1][j+1][k1+1][max(k2-1,0)])%mod;
44                     if(k2<k&&(i-j)<m)f[i+1][j][max(k1-1,0)][k2+1]=(f[i][j][k1][k2]+f[i+1][j][max(k1-1,0)][k2+1])%mod;
45                 }
46     int ans=0;
47     for0(i,k)
48         for0(j,k)
49             ans=(ans+f[n+m][n][i][j])%mod;
50     printf("%d",ans);
51     return 0;
52 }
View Code

 

posted @ 2016-02-12 09:24  HTWX  阅读(123)  评论(0编辑  收藏  举报