题意:要求任意连续子序列中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 ", ans); } return 0; }