DP ZOJ 2745 01-K Code

 

题目传送门

题意:要求任意连续子序列中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;
}

  

posted @ 2016-03-17 12:53  Running_Time  阅读(238)  评论(0编辑  收藏  举报