zoukankan      html  css  js  c++  java
  • poj3252(数位dp)

    poj3252

    题意:求一个区间内Round Numbers(二进制0的个数不小于1的个数)的个数

    解题思路:我们可以定义某个状态dp【pos】【num0】【num1】,pos为当前数位,num0为二进制中0的个数,num1为二进制中1的个数,由于有前导0的干扰,我们可以设置一个全局变量来标记何时开始记录0,1的个数。

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<stack>
    #include<cstdio>
    #include<map>
    #include<set>
    #include<string>
    #include<queue>
    using namespace std;
    #define inf 0x3f3f3f3f
    typedef long long ll;
    inline ll gcd(ll i,ll j){
        return j==0?i:gcd(j,i%j);
    }
    inline ll lcm(ll i,ll j){
        return i/gcd(i,j)*j;
    }
    const int maxn=65;
    ll dp[maxn][maxn][maxn];
    int sa[maxn],work;
    ll dfs(int pos,int num0,int num1,bool limit){
        if(pos==-1){
            work=1;
            return num0>=num1; 
        }
        if(!limit&&dp[pos][num0][num1]!=-1&&work){
            return dp[pos][num0][num1];
        }
        int up=limit?sa[pos]:1;
        ll ans=0;
        for(int i=0;i<=up;i++){
            if(work)
            ans+=dfs(pos-1,num0+(i==0),num1+(i==1),limit&&i==up);
            else{
                    ans+=dfs(pos-1,0,0,limit&&i==up);
            }
        }
        if(!limit&&work){
            dp[pos][num0][num1]=ans;
        }
        return ans;
    }
    ll solve(ll s){
        int len=0;
        while(s){
            sa[len++]=s%2;
            s/=2;
        }
        work=0;
        return dfs(len-1,0,0,true);
    }
    int main(){
        ios::sync_with_stdio(false);
        cin.tie(0);
        ll l,r;
        memset(dp,-1,sizeof(dp));
        while(~scanf("%lld%lld",&l,&r)){
                printf("%lld
    ",solve(r)-solve(l-1));
        }
        return 0;
    }
  • 相关阅读:
    webpack4 plugins 篇
    webpack4 打包静态资源
    babel 7 简单指北
    JS: 深拷贝
    JS: 数组的循环函数
    async await 的执行
    redux
    TCP通信
    理解Javascript的原型和原型链
    「译」forEach循环中你不知道的3件事
  • 原文地址:https://www.cnblogs.com/Zhi-71/p/10426946.html
Copyright © 2011-2022 走看看