挺简单的一个dp..适合练手
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e8;
ll dp[205][105][12][12];//到了第i个第一种分配了l个第一种连续j第二种连续k的方案数
int main()
{
int n1,n2,k1,k2;
cin>>n1>>n2>>k1>>k2;
dp[1][1][1][0]=1;
dp[1][0][0][1]=1;
/*
首先分析状态转移再写for.
dp[i][l][j][0]=;//假设j是1,那么可以把i-l的全部写下. 假如j不是1,那么只能从dp[i-1][l-1][j-1][0]转移
dp[i][l][0][k]=;
*/
for(int i=2;i<=(n1+n2);i++)
{
for(int l=0;l<=min(n1,i);l++)
{
for(int j=1;j<=min(l,k1);j++)//分配给了第一个
{
if(j==1)
{
for(int k=1;k<=min(min(i-l,k2),n2);k++)
{
dp[i][l][j][0]=(dp[i][l][j][0]+dp[i-1][l-1][0][k])%mod;
}
}
else dp[i][l][j][0]=(dp[i][l][j][0]+dp[i-1][l-1][j-1][0])%mod;
}
for(int j=1;j<=min(min(i-l,k2),n2);j++)//分配给了第二个
{
if(j==1)
{
for(int k=1;k<=min(l,k1);k++)
{
dp[i][l][0][j]=(dp[i][l][0][j]+dp[i-1][l][k][0])%mod;
}
}
else dp[i][l][0][j]=(dp[i][l][0][j]+dp[i-1][l][0][j-1])%mod;
}
}
// cout<<dp[3][2][1][0]<<endl;//1 2 1
}
ll ans=0;
for(int i=1;i<=min(n1,k1);i++) ans=(ans+dp[n1+n2][n1][i][0])%mod;
for(int i=1;i<=min(n2,k2);i++) ans=(ans+dp[n1+n2][n1][0][i])%mod;
cout<<ans<<endl;
return 0;
}

京公网安备 11010502036488号