【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 }