【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

 

转载于:https://www.cnblogs.com/itcsl/p/7115055.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值