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;
}
时间: 2024-08-02 06:58:50

Light OJ 1032 - Fast Bit Calculations(数位DP)的相关文章

light oj 1422 - Halloween Costumes (区间dp)

1422 - Halloween Costumes PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Gappu has a very busy weekend ahead of him. Because, next weekend is Halloween, and he is planning to attend as many parties as he can. Since it's Ha

Light OJ 1032

数位dp,许多数位dp需要统计某种模式(子串)出现的数量,这种题通常需要在递归参数中加入高位已经出现过的模式的数量. #include <cstdio> #include <cstring> using namespace std; #define D(x) const int MAX_DIGIT = 40; long long n; int f[MAX_DIGIT]; long long memoize[MAX_DIGIT][2][MAX_DIGIT]; int cnt; int

Light OJ 1031 - Easy Game(区间DP)

题目大意: 给你一个n,代表n个数字,现在有两个选手,选手A,B轮流有有一次机会,每个选手一次可以得到一个或者多个数字,从左侧或者右侧,但是不能同时从两边取数字,当所有的数字被取完,那么游戏结束.然后计算每个选手所得到数字的总和,每个选手都尽量让自己的分数比较多,选手A先开始取数.假设每个选手取得数字都是最优的,问A最多比B多多少分数,. 题目分析: 记忆化搜索,区间DP. dp[该谁取了][左区间L][右区间] = 所能取到的最大值. 做下简单的预处理,得到区间L-R之间的和. 然后状态转移

Light oj 1044 - Palindrome Partitioning(区间dp)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1044 dp[i][j]表示i到j直接的最小回文区间个数,直接看代码 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e3 + 5; 4 int dp[N][N], inf = 1e9; 5 char str[N]; 6 bool judge(int l, int r) { 7 for(int i

Light OJ Dynamic Programming

免费做一样新 1004 - Monkey Banana Problem 号码塔 1005 - Rooks 排列 1013 - Love Calculator LCS变形 dp[i][j][k]对于第一个字符串i 到jLCS为k的方案数 1068 - Investigation 数位dp 能被K整数且各位数字之和也能被K整除的数 dp[i][j][k] 到第i位每位数字之和的余数为j 当前数字余数为k 1079 - Just another Robbery 01背包 全部钱之和为背包体积 不被抓的

lightoj1032_数位dp

题目链接:http://lightoj.com/volume_showproblem.php?problem=1032 1032 - Fast Bit Calculations    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB A bit is a binary digit, taking a logical value of either 1 or 0 (also referred to

light oj 1031(数位DP)

求一段区间中,每个十进制数所对应的二进制数中连续的1的个数之和. 设dp[i][0]代表长度为i的二进制数,首位为0,所含有的连续的1的个数之和. dp[i][1]代表长度为i的二进制数,首位为1,所含有的连续的1的个数之和. a: d[i][1]=d[i-1][0]+d[i-1][1]+(1<<(i-2)); b: d[i][0]=d[i-1][0]+d[i-1][1]; 这里面有一个需要注意的地方是,假设有一个数字是111,那么它含有2个连续的1,具体体现在 方程上是分两次计算的,一个是a

LightOJ1032 Fast Bit Calculations(数位DP)

显然数位DP. dp[i][j]表示所有末尾为j的i位二进制数相邻位的数量和 初始状态dp[2][1]=1 从长度i-1转移到长度i就是在i-1位的末尾添上0或1,转移方程就是: dp[i][0]=dp[i-1][0]+dp[i-1][1] dp[i][1]=dp[i-1][0]+dp[i-1][1]+2i-2 预处理完后,就可以通过这个计算出[0,n]区间的数量和,还是感觉数位DP的这一步挺棘手的,具体问题具体分析吧.. 1 #include<cstdio> 2 #include<cs

Timus OJ 1057 数位dp

http://acm.timus.ru/problem.aspx?space=1&num=1057 1057. Amount of Degrees Time limit: 1.0 second Memory limit: 64 MB Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactlyK different integer degrees of B.