数位dp

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int N=25;
int a[N],len;
long long l,r,dp[N][N];
long long dfs(int pos,int st,long long sum,int lead,int limit)
{
    if(pos>len) return sum;
    if((dp[pos][sum]!=-1&&(!limit)&&(!lead))) return dp[pos][sum];
    long long ret=0;
    int res=limit?a[len-pos+1]:9;
    for(int i=0;i<=res;i++)
    {
        if((!i)&&lead) ret+=dfs(pos+1,st,sum,1,i==res&&limit);
        else if(i||!lead){
            if(i==st){
                ret+=dfs(pos+1,st,sum+1,0,i==res&&limit);
            }
            else{
                ret+=dfs(pos+1,st,sum,0,i==res&&limit);
            }
        }
        else if((i||!lead)&&i==st){
            ret+=dfs(pos+1,st,sum+1,0,i==res&&limit);
        }
    }
    if(!limit&&!lead) dp[pos][sum]=ret;
    return ret;
}
long long part(long long x,int now)
{
    len=0;
    while(x) a[++len]=x%10,x/=10;
    memset(dp,-1,sizeof (dp));
    return dfs(1,now,0,1,1);
}
int main()
{
    scanf("%lld%lld",&l,&r);
    for(int i=0;i<=9;i++){
        if(l){
            printf("%lld ",part(r,i)-part(l-1,i));
        }
        else{
            printf("%lld ",part(r,i)-part(l,i));
        }
    }
    return 0;
}
posted @ 2019-07-16 13:40  prestige  阅读(121)  评论(0编辑  收藏  举报