原题传送门
题意:
求由n个0、m个1组成,且满足任意子串0的数量和1的数量差绝对值不超过k的01串数量。n, m≤150,k≤20。
d
p
i
,
j
,
k
,
l
dp_{i,j,k,l}
dpi,j,k,l表示现在已经有
i
i
i个0,
j
j
j个1,所有后缀中0最多比1多
k
k
k个,1最多比0多
l
l
l个
那么枚举
i
=
[
1
,
n
]
,
j
=
[
1
,
m
]
,
k
=
[
1
,
K
]
,
l
=
[
1
,
K
]
i=[1,n],j=[1,m],k=[1,K],l=[1,K]
i=[1,n],j=[1,m],k=[1,K],l=[1,K]
那么对于一个
d
p
[
i
]
[
j
]
[
k
]
[
l
]
dp[i][j][k][l]
dp[i][j][k][l]可以推到哪里去?
若后一位放了个0,那么可以推到
d
p
[
i
+
1
]
[
j
]
[
k
+
1
]
[
m
a
x
(
0
,
l
−
1
)
]
dp[i+1][j][k+1][max(0,l-1)]
dp[i+1][j][k+1][max(0,l−1)]
若后一位放了个1,那么可以推到
d
p
[
i
]
[
j
+
1
]
[
m
a
x
(
0
,
k
−
1
)
]
[
l
+
1
]
dp[i][j+1][max(0,k-1)][l+1]
dp[i][j+1][max(0,k−1)][l+1]
最终 A N S = ∑ i = 1 K ∑ j = 1 K d p [ n ] [ m ] [ i ] [ j ] ANS=\sum_{i=1}^{K}\sum_{j=1}^{K}dp[n][m][i][j] ANS=∑i=1K∑j=1Kdp[n][m][i][j]
Code:
#include <bits/stdc++.h>
#define maxn 155
#define maxm 25
#define qy 12345678
using namespace std;
int n, m, K, dp[maxn][maxn][maxm][maxm];
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
int main(){
n = read(), m = read(), K = read();
dp[0][0][0][0] = 1;
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= m; ++j)
for (int k = 0; k <= K; ++k)
for (int l = 0; l <= K; ++l){
(dp[i + 1][j][k + 1][max(0, l - 1)] += dp[i][j][k][l]) %= qy;
(dp[i][j + 1][max(0, k - 1)][l + 1] += dp[i][j][k][l]) %= qy;
}
int ans = 0;
for (int i = 0; i <= K; ++i)
for (int j = 0; j <= K; ++j)
(ans += dp[n][m][i][j]) %= qy;
printf("%d\n", ans);
return 0;
}