[poj 3252]数位dp前导0的处理

通过这个题对于数位dp中前导0的处理有了新的认识。

题目链接:http://poj.org/problem?id=3252

//http://poj.org/problem?id=3252

#include<cstdio>
#include<cstring>
using namespace std;

int b[40];
int dp[40][80][2];

int dfs(int pos,int preok,int more,int pre0)
{
    if (pos==-1) return more==0?1:0;
    if (preok && dp[pos][more+40][pre0]!=-1) return dp[pos][more+40][pre0];
    int up=preok?1:b[pos];
    int ans=0;
    for (int i=0;i<=up;i++)
    {
        if (i<b[pos]||preok) ans+=dfs(pos-1,1,more+(i==1?1:pre0-1),pre0&&!i);
        else ans+=dfs(pos-1,0,more+(i==1?1:pre0-1),pre0&&!i);
    }
    if (preok) dp[pos][more+40][pre0]=ans;
    //printf("pos=%d preok=%d more=%d pre0=%d ans=%d\n",pos,preok,more,pre0,ans);
    return ans;
}

int solve(int n)
{
    if (n<0) return 0;
    int cnt=0;
    int now=n;
    do{
        b[cnt]=now%2;
        now/=2;
        cnt++;
    }while (now);
    int ans=0;
    for (int i=0;i<=cnt;i++)
        ans+=dfs(cnt-1,0,i,1);
    return ans;
}

int main()
{
    int n,m;
    memset(dp,-1,sizeof(dp));
    while (~scanf("%d%d",&n,&m))
    {
        printf("%d\n",solve(m)-solve(n-1));
    }
    return 0;
}

 

posted @ 2017-07-19 01:28  ACMsong  阅读(694)  评论(0编辑  收藏  举报