POJ3252 Round Numbers(数位dp)

这里只需先转化乘二进制后,记录前面有几个0和几个1,并且记录前导0状态,因为前导0会影响答案

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
#include<string>
#include<vector>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int l,r;
vector<int> num;
int len;
int f[33][33][33][2][2];
int dfs(int cur,int p1,int p2,int flag,int g){
    if(cur==len)
    return p1>=p2;
    if(f[cur][p1][p2][flag][g]!=-1)
        return f[cur][p1][p2][flag][g];
    int v=1;
    if(flag)
        v=num[cur];
    int ans=0;
    int i;
    for(i=0;i<=v;i++){
        if(g){
            if(!i)
                ans+=dfs(cur+1,p1,p2,flag&&(i==v),1);
            else{
                ans+=dfs(cur+1,p1,p2+1,flag&&(i==v),0);
            }
        }
        else{
            ans+=dfs(cur+1,p1+(i==0),p2+(i==1),flag&&(i==v),0);
        }
    }
    return f[cur][p1][p2][flag][g]=ans;
}
int solve(int t){
    num.clear();
    int i;
    memset(f,-1,sizeof f);
    while(t){
        num.push_back(t%2);
        t/=2;
    }
    len=(int)num.size();
    reverse(num.begin(),num.end());
    return dfs(0,0,0,1,1);
}
int main(){
    while(cin>>l>>r)
    cout<<solve(r)-solve(l-1)<<endl;
    return 0;
}
View Code

 

posted @ 2020-04-18 21:32  朝暮不思  阅读(122)  评论(0编辑  收藏  举报