poj 3252 (数位dp)

题目链接:

http://poj.org/problem?id=3252
做了牛客多校那个数位 d p 之后,哇这种题真是太简单我也能做了T_T
我还是喜欢用 m a p 来当 d p ,不想去弄个偏移量
之前RE了几发,是因为这个是存的二进制位,我只开了 20 。。。

//#include"bits/stdc++.h"
#include"iostream"
#include"map"
using namespace std;
typedef long long LL;
int a[100];
map<int,LL>dp[100][3];
LL dfs(int pos,int pre,int sum,bool lim)
{
    if(pos==-1)
    {
        if(sum>=0)return 1;
        else return 0;
    }
    if(lim==0&&dp[pos][pre][sum])return dp[pos][pre][sum];
    int up=lim?a[pos]:1;
    LL cnt=0;
    for(int i=0;i<=up;i++)
    {
        if(pre<=1)cnt+=dfs(pos-1,i,sum+(i==0?1:-1),lim&&i==up);
        else    //从高位往低位枚举还没出现过1,也就是说全是前导零 
        {
            if(i)cnt+=dfs(pos-1,i,sum-1,lim&&i==up);//终于出现1了
            else cnt+=dfs(pos-1,pre,sum,lim&&i==up);//还没出现过1 
        }
    }
    if(lim==0)dp[pos][pre][sum]=cnt; 
    return cnt;
}
LL solve(LL n)
{
    int pos=-1;
    while(n)
    {
        a[++pos]=n&1;
        n>>=1;
    }
    return dfs(pos,2,0,true);
}
int main()
{
    int L,R;
    while(cin>>L>>R)
    {
        cout<<solve(R)-solve(L-1)<<endl;
    } 
}

猜你喜欢

转载自blog.csdn.net/SwustLpf/article/details/81450586