LightOJ - 1032 Fast Bit Calculations(数位DP)

来源:互联网 发布:如何加强网络文化建设 编辑:程序博客网 时间:2024/06/06 08:31

题目大意:求0-n的二进制数的所有相邻1的数量
相邻1指两个1相邻

解题思路:数位dp,dp[i][j][k]表示第i个位置,前一个数是j,到目前为止相邻的1有k个的相邻1的总数

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int N = 65;int digit[N];LL dp[N][3][N];int cas = 1;LL dfs(int pos, int pre, LL num, int limit, int first) {    if (pos == 0) return num;    if (!limit && !first && ~dp[pos][pre][num]) return dp[pos][pre][num];    int n = limit ? digit[pos] : 1;    LL ans = 0;    for (int i = 0; i <= n; i++) {        if (first) ans += dfs(pos - 1, i, 0, limit && i == n, first && i == 0);        else {            if (i == 1 && pre == 1) ans += dfs(pos - 1, i, num + 1, limit && i == n, first && i == 0);            else ans += dfs(pos - 1, i, num, limit && i == n, first && i == 0);        }    }    if (!limit && !first) dp[pos][pre][num] = ans;    return ans;} void solve() {    int num, cnt = 0;    memset(dp, -1, sizeof(dp));    scanf("%d", &num);    while (num) {        digit[++cnt] = num % 2;        num /= 2;    }    printf("Case %d: %lld\n", cas++, dfs(cnt, 0, 0, 1, 1));}int main() {    int test;    scanf("%d", &test);    while (test--) solve();    return 0;}
0 0