【问题描述】
今天是hidadz小朋友的生日,她邀请了许多朋友来参加她的生日party。 hidadz带着朋友们来到花园中,打算坐成一排玩游戏。为了游戏不至于无聊,就座的方案应满足如下条件:
对于任意连续的一段,男孩与女孩的数目之差不超过k。
很快,小朋友便找到了一种方案坐了下来开始游戏。hidadz的好朋友Susie发现,这样的就座方案其实是很多的,所以大家很快就找到了一种,那么到底有多少种呢?热爱数学的hidadz和她的朋友们开始思考这个问题……
假设参加party的人中共有n个男孩与m个女孩,你是否能解答Susie和hidadz的疑问呢?由于这个数目可能很多,他们只想知道这个数目除以12345678的余数。
【输入文件】
输入文件party.in仅包含一行共3个整数,分别为男孩数目n, 女孩数目m, 常数k。
【输出文件】
输出文件party.out应包含一行,为题中要求的答案。
思路:n^2*k^2的dp
1 #include<iostream>
2 #include<cstring>
3 #include<cmath>
4 #include<cstring>
5 using namespace std;
6 #define mod 12345678
7 int dp[151][151][21][21];
8 int n,m,k;
9 int main()
10 {
11 freopen("party.in","r",stdin);
12 freopen("party.out","w",stdout);
13 memset(dp,0,sizeof(dp));
14 scanf("%d%d%d",&n,&m,&k);
15 int i,j,boys,girls,boys_k,girls_k,ans=0;
16 dp[1][0][1][0]=1;
17 dp[0][1][0][1]=1;
18 for(i=1;i<n+m;i++)
19 for(boys=0;boys<=n;boys++)
20 {
21 girls=i-boys;
22 if(girls>m||girls<0) continue;
23 for(boys_k=0;boys_k<=k;boys_k++)
24 for(girls_k=0;girls_k<=k;girls_k++)
25 {
26 //+boy
27 if(boys_k<k&&boys<n)
28 {
29 if(girls_k==0)
30 dp[boys+1][girls][boys_k+1][0]=(dp[boys][girls][boys_k][0]+dp[boys+1][girls][boys_k+1][0])%mod;
31 else
32 dp[boys+1][girls][boys_k+1][girls_k-1]=(dp[boys][girls][boys_k][girls_k]+dp[boys+1][girls][boys_k+1][girls_k-1])%mod;
33 }
34 if(girls_k<k&&girls<m)
35 {
36 if(boys_k==0)
37 dp[boys][girls+1][0][girls_k+1]=(dp[boys][girls][0][girls_k]+dp[boys][girls+1][0][girls_k+1])%mod;
38 else
39 dp[boys][girls+1][boys_k-1][girls_k+1]=(dp[boys][girls][boys_k][girls_k]+dp[boys][girls+1][boys_k-1][girls_k+1])%mod;
40 }
41 }
42 }
43 for(i=0;i<=k;i++)
44 for(j=0;j<=k;j++)
45 ans=(ans+dp[n][m][i][j])%mod;
46 printf("%d\n",ans);
47 return 0;
48 }