题意:要求任意连续子序列中0和1的数量差不超过k的方案数
分析:想好状态其实不难。dp[i][j][k]表示考虑前i长度,后缀中最大的 sum(0) - sum(1) = j, sum (1) - sum (0) = k的方案数,合并以下可以得到最大的|sum(0) - sum(1)| = j + k,所以j+k <= K,最后考虑当前i放0或1就可以转移状态了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll dp[66][7][7];
int main() {
int N, K;
while (scanf ("%d%d", &N, &K) == 2) {
memset (dp, 0, sizeof (dp));
dp[0][0][0] = 1;
for (int i=1; i<=N; ++i) {
for (int j=0; j<=K; ++j) {
for (int k=0; k<=K; ++k) {
if (j + k > K) continue;
dp[i][max (j-1, 0)][k+1] += dp[i-1][j][k];
dp[i][j+1][max (k-1, 0)] += dp[i-1][j][k];
}
}
}
ll ans = 0;
for (int i=0; i<=K; ++i) {
for (int j=0; j<=K; ++j) {
if (i + j > K) continue;
ans += dp[N][i][j];
}
}
printf ("%lld\n", ans);
}
return 0;
}