挺简单的一个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; }