E - Round Numbers-二进制数位DP

  • E - Round Numbers

  •  POJ - 3252 
  • 题意:Round Number 被称为其二进制形式中0的个数>=1的个数。求[x,y]区间内“Round Number”的个数.
  • 初步想法正常数位dp进行搜缩搜到一个数时去getsum一下里面0,1数,但没想好如何记忆化,而且题目的要求按照十进制的数位进行 记忆化确实没有意义,这里他想要找的数字都是对二进制有要求所以直接按照二进制进行数位dp。dp数组三维分别代表数位0的个数1的个数 ,所以数位dp要根据题目的要求去进行搜索 。灵活多变。
  • #include<iostream>
    #include<stdio.h>
    #include<cstring>
    using namespace std;
    #define ll long long
    #define maxn 60
    int a[maxn],dp[maxn][maxn][maxn];
    ll  l,r;
    ll dfs(int len,bool first,int num0,int num1,bool limit)
    {
        if(len==0)return num0>=num1;
        if(!limit&&dp[len][num0][num1]>=0)
            return dp[len][num0][num1];
        ll ans=0;
        int up=(limit?a[len]:1);
        for(int i=0; i<=up; i++)
        {
            int t0=num0+1;
            int t1=num1+1;
            if(i==0)
                t0++;
            else
                t1++;
            if(first&&i==0)
                ans+=dfs(len-1,1,0,0,limit&&i==up);
            else
                ans+=dfs(len-1,0,t0,t1,limit&&i==up);
        }
        if(!limit)
            dp[len][num0][num1]=ans;
        return ans;
    }
    ll solve(ll num)
    {
        ll cnt=0;
        while(num)
        {
            a[++cnt]=num%2;
            num/=2;
        }
        return dfs(cnt,1,0,0,1);
    }
    int main()
    {
        memset(dp,-1,sizeof(dp));
        scanf("%lld%lld",&l,&r);
        printf("%lld\n",solve(r)-solve(l-1));
        return 0;
    }
    
  •  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值