【dp】D. Caesar's Legions

https://www.bnuoj.com/v3/contest_show.php?cid=9146#problem/D

【题意】给定n1个A,n2个B,排成一排,要求A最多能连续k1个紧挨着,B最多能连续k2个紧挨着。问排队的方案数。

【思路】dp。dp[i][j][k][l]表示当前已经排了i个A,j个B,有k个A紧挨着,l个B紧挨着,那么由dp[i][j][k][l]可以推出dp[i+1][j][k+1][0]和dp[i][j+1][0][l+1]

初始化dp[0][0][0][0]为1,最后的结果就是dp[n1][n2][0][l]+dp[n1][n2][k][0](l和k分别小于k2,k1)

【Accepted】

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<string>
 6 #include<cstring>
 7 
 8 using namespace std;
 9 typedef long long ll;
10 typedef double db;
11 const int mod=1e8;
12 int dp[105][105][12][12];
13 int n1,n2,k1,k2;
14 int main()
15 {
16     scanf("%d%d%d%d",&n1,&n2,&k1,&k2);
17     memset(dp,0,sizeof(dp));
18     dp[0][0][0][0]=1;
19     for(int i=0;i<=n1;i++)
20     {
21         for(int j=0;j<=n2;j++)
22         {
23             for(int k=0;k<=k1;k++)
24             {
25                 for(int l=0;l<=k2;l++)
26                 {
27                     if(i+1<=n1&&k+1<=k1)
28                     {
29                         dp[i+1][j][k+1][0]=(dp[i+1][j][k+1][0]+dp[i][j][k][l])%mod;
30                     }
31                     if(j+1<=n2&&l+1<=k2)
32                     {
33                         dp[i][j+1][0][l+1]=(dp[i][j+1][0][l+1]+dp[i][j][k][l])%mod;
34                     }
35                 }
36             }
37         }
38     }
39     int ans=0;
40     for(int i=0;i<=k1;i++)
41     {
42         ans=(ans+dp[n1][n2][i][0])%mod;
43     }
44     for(int i=0;i<=k2;i++)
45     {
46         ans=(ans+dp[n1][n2][0][i])%mod;
47     }
48     cout<<ans<<endl; 
49     return 0;
50 }
View Code

 

posted @ 2017-07-04 09:48  shulin15  阅读(213)  评论(0编辑  收藏  举报