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