数位dp

来源:互联网 发布:javascript知识点总结 编辑:程序博客网 时间:2024/05/29 16:40
#include<bits/stdc++.h>using namespace std;typedef long long LL;LL l,r;LL dp[10][20][10];//dp[k][i][j]:第i位是数字j后面位数放任意数字,数字k出现的次数(k包括0)LL f(int pos){    LL s=1;    for(LL i=1;i<pos;i++) s*=10;    return s;}void init(){    for(LL k=0;k<=9;k++)     for(LL i=1;i<=19;i++)      for(LL j=0;j<=9;j++)      {          for(LL p=0;p<=9;p++)          {               dp[k][i][j]=dp[k][i][j]+dp[k][i-1][p];          }          if(j==k) dp[k][i][j]+=f(i);      }}LL cal(LL x,LL tmp){    LL a[20],num=0;    while(x)    {        a[++num]=x%10;        x/=10;    }    LL ans=0;    for(LL i=num;i>=1;i--)    {        for(LL j=0;j<a[i];j++)        {           ans+=dp[tmp][i][j];        }    }    if(tmp==0)//统计0时特殊处理下    {        LL s=0;        for(int i=num;i>=1;i--) s=s*10+1;        ans-=s;    }    for(LL i=num;i>=1;i--)    {        if(a[i]==tmp)        {            LL s=0;            for(LL j=i-1;j>=1;j--) s=s*10+a[j];            ans+=s+1;        }    }    return ans;}int main(){    init();    while(scanf("%lld%lld",&l,&r)!=EOF)    {        for(LL i=0;i<=9;i++)        {            cout<<cal(r,i)-cal(l-1,i)<<endl;        }    }    return 0;}

原创粉丝点击