题目描述
今天是hidadz小朋友的生日,她邀请了许多朋友来参加她的生日party。 hidadz带着朋友们来到花园中,打算坐成一排玩游戏。为了游戏不至于无聊,就座的方案应满足如下条件:对于任意连续的一段,男孩与女孩的数目之差不超过k。很快,小朋友便找到了一种方案坐了下来开始游戏。hidadz的好朋友Susie发现,这样的就座方案其实是很多的,所以大家很快就找到了一种,那么到底有多少种呢?热爱数学的hidadz和她的朋友们开始思考这个问题…… 假设参加party的人中共有n个男孩与m个女孩,你是否能解答Susie和hidadz的疑问呢?由于这个数目可能很多,他们只想知道这个数目除以12345678的余数。
仅包含一行共3个整数,分别为男孩数目n, 女孩数目m, 常数k。
应包含一行,为题中要求的答案。
样例输入
1 2 1
样例输出
1
分析
这个题想都不用想一看就是DP,但状态怎么找呢,可以确定的是,男孩和女孩的人数一定占两个状态,因为这个是可以确定他们的方案数的,剩下的我想维护男生与女生之间的差值,但这样显然是会出问题的,假如差值为2,那么有可能男生比女生多2,有可能女生比男生多2,这是两个方案,而这么定义状态的话就会出现少算方案数的情况,所以我们必须要维护男生比女生多的人数,女生比男生多的人数,这样状态就有了,定义dp[a][b][c][d]为共有a个女孩,b个男孩,男孩比女孩多c,女孩比男孩多d,那么每放一个人,就有两种可能,男生或女生,转移两次即可。
1 #include<iostream> 2 #define g dp[i][j][c][d] 3 #define mod 12345678 4 using namespace std; 5 int dp[160][160][25][25]; 6 int main(){ 7 int n,m,k; 8 cin>>n>>m>>k; 9 dp[0][0][0][0]=1; 10 for(int i=0;i<=m;i++) 11 for(int j=0;j<=n;j++) 12 for(int c=0;c<=k;c++) 13 for(int d=0;d<=k;d++){ 14 dp[i][j+1][c+1][max(d-1,0)]=(dp[i][j+1][c+1][max(d-1,0)]+g)%mod; 15 dp[i+1][j][max(c-1,0)][d+1]=(dp[i+1][j][max(c-1,0)][d+1]+g)%mod; 16 } 17 int ans=0; 18 for(int i=0;i<=k;i++) 19 for(int j=0;j<=k;j++) 20 ans=(ans+dp[m][n][i][j])%mod; 21 cout<<ans<<endl; 22 }