Light OJ 1032 - Fast Bit Calculations(数位DP)

题目大意:

一个数字把他看成二进制数字,数字里又会一些相邻的1,问从0到n至间所有相邻1的总和是多少?
 
分解成2进制数字,然后数位DP就行了。
 
========================================================================
 
 
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
const int INF = 1e9+7;
const int MAXN = 255;
int bit[40];///dp[位数][首位是否是1]
LL dp[40][60][2];
LL DFS(int pos,int num,bool Is1,int Lim)///num代表这个数字里面成对的
{
    if(pos == -1)
        return num;
    if(dp[pos][num][Is1] != -1 && !Lim)
        return dp[pos][num][Is1];
    int end = Lim?bit[pos]:1;

    LL ans = 0, k = 0;
    for(int i=0; i<=end; i++)
    {
        if(i == 1 && Is1) k = 1;
        ans += DFS(pos-1, num+k, i==1, Lim && i==end);
    }
    if(!Lim)
        dp[pos][num][Is1] = ans;
    return ans;
}


LL solve(int n)
{
    int len = 0;
    while(n)
    {
        bit[len++] = n%2;
        n /= 2;
    }
    return DFS(len-1, 0, false, true);
}
int main()
{
    int T, cas = 1, n;
    memset(dp, -1, sizeof(dp));
    scanf("%d", &T);
    while(T --)
    {
        scanf("%d", &n);
        printf("Case %d: %lld\n",cas++, solve(n));
    }

    return 0;
}

 

posted @ 2015-10-26 19:25  向前走丶不回首  阅读(104)  评论(0编辑  收藏  举报