https://codeforces.com/problemset/problem/118/D
这个题目有点思路,转移方程写错了。
这个题目看到数据范围之后发现很好dp,
dp[i][j][k1][k2]代表的是前面i个1 j 个0,到第 i+j 为有连续 k1 个 1,连续 k2 个0形成排列的方案数。
这个要注意其中k1 k2一定有一个是0
状态转移方程 dp[i+1][j][k1+1][0]+=dp[i][j][k1][k2] dp[i][j+1][0][k2+1]+=dp[i][j][k1][k2]
如果k1==0 那么就会从很多状态转移过来
但是如果k1!=0就只会从k1这个状态转移过来。
这个就是这个状态转移方程为什么这么写的原因。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
#define inf 0x3f3f3f3f
#define debug(x) cout<<"-----"<<" x = "<<x<<"-----"<<endl
using namespace std;
const int mod = 1e8;
const int maxn = 1e5 + 10;
int dp[110][110][12][12];
int main()
{
int n1, n2, k1, k2;
scanf("%d%d%d%d", &n1, &n2, &k1, &k2);
memset(dp, 0, sizeof(dp));
int ans = 0;
dp[0][0][0][0] = 1;
for(int i=0;i<=n1;i++)
{
for(int j=0;j<=n2;j++)
{
for(int l=0;l<=k1;l++)
{
for(int r=0;r<=k2;r++)
{
if(i!=n1&&l!=k1)
{
dp[i + 1][j][l + 1][0] += dp[i][j][l][r];
dp[i + 1][j][l + 1][0] %= mod;
}
if(j!=n2&&r!=k2)
{
dp[i][j + 1][0][r + 1] += dp[i][j][l][r];
dp[i][j + 1][0][r + 1] %= mod;
}
}
}
}
}
for (int i = 0; i <= k1; i++)
{
ans += dp[n1][n2][i][0];
ans %= mod;
}
for(int i=0;i<=k2;i++)
{
ans += dp[n1][n2][0][i];
ans %= mod;
}
printf("%d
", ans);
return 0;
}