Description
给定两个正整数
Input
输入文件中仅包含一行两个整数
Output
输出文件中包含一行10个整数,分别表示0-9在
Sample Input
1 99
Sample Output
9 20 20 20 20 20 20 20 20 20
HINT
30%的数据中,
100%的数据中,
Source
Day1
思路
第一次写数位dp。。。顾名思义,数位dp就是对每个数位进行dp。一般来说,数位dp的适用范围是求一个区间
代码
#include <cstdio>
#include <cmath>
const int maxn=12;
struct data
{
long long num[10];
data operator +(const data &other)
{
data res;
for(int i=0; i<=9; i++)
{
res.num[i]=num[i]+other.num[i];
}
return res;
}
};
data f[maxn+1][10];
long long t[maxn+1],a,b;
int init();
data calc(long long n);
int main()
{
init();
scanf("%lld%lld",&a,&b);
data x=calc(a-1),y=calc(b);
for(int i=0; i<9; i++)
{
printf("%lld ",y.num[i]-x.num[i]);
}
printf("%lld\n",y.num[9]-x.num[9]);
return 0;
}
int init()
{
t[1]=1;
for(int i=2; i<=13; i++)
{
t[i]=t[i-1]*10ll;
}
for(int i=0; i<=9; i++)
{
f[1][i].num[i]=1;
}
for(int i=2; i<=12; i++)
{
for(int j=0; j<=9; j++)
{
for(int k=0; k<=9; k++)
{
f[i][k]=f[i][k]+f[i-1][j];
f[i][k].num[k]+=t[i-1];
}
}
}
return 0;
}
data calc(long long n)
{
data ans;
ans.num[0]=1;
for(int i=1; i<=9; i++)
{
ans.num[i]=0;
}
if(!n)
{
return ans;
}
int len=log(n)/log(10)+1;
for(int i=1; i<len; i++)
{
for(int j=1; j<=9; j++)
{
ans=ans+f[i][j];
}
}
int h=n/t[len];
n%=t[len];
for(int i=1; i<h; i++)
{
ans=ans+f[len][i];
}
ans.num[h]+=n+1;
for(int i=len-1; i>0; i--)
{
h=n/t[i];
n%=t[i];
for(int j=0; j<h; j++)
{
ans=ans+f[i][j];
}
ans.num[h]+=n+1;
}
return ans;
}