题解:
我们统计前面的模数?
按照平常的思维,会定义
dp[i][j][k]
d
p
[
i
]
[
j
]
[
k
]
为当前扫到前i位,数位和为
j
j
,数字取模数位和后为,跑一遍
R
R
的再跑一遍
L−1
L
−
1
的
dp
d
p
然而跑一遍是不行的…因为前面的取模和后面的取模没有关系,之间是不能转移的….
那该如何思考?
所以这道题需要枚举数位和(也就是模数),对每个数位和都跑一次
dfs
d
f
s
,因为数字在
longlong
l
o
n
g
l
o
n
g
范围内,数位和最大只会有
9∗18=162
9
∗
18
=
162
,是可过的。
Code:
C
o
d
e
:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll f[21][200][200][2],a,b;
int n,sum=9*18+1,dight[20];
ll find(ll x,int mod)
{
if(!x)return 0;
memset(f,0,sizeof(f));
int num=0;
while(x)
{
dight[++num]=x%10;
x/=10;
}
f[num+1][0][0][0]=1;
for(int i=num+1;i>1;i--)
for(int j=0;j<=mod;j++)
for(int k=0;k<mod;k++)
{
if(!f[i][j][k][0]&&!f[i][j][k][1])continue;
for(int p=0;p<=9;p++)
{
if(p<dight[i-1]&&(j+p<=mod))f[i-1][j+p][(10*k+p)%mod][1]+=f[i][j][k][0];else
if(p==dight[i-1]&&(j+p<=mod))f[i-1][j+p][(10*k+p)%mod][0]+=f[i][j][k][0];
if(f[i][j][k][1]&&(j+p<=mod)) f[i-1][j+p][(10*k+p)%mod][1]+=f[i][j][k][1];
}
}
return f[1][mod][0][0]+f[1][mod][0][1];
}
int main()
{
scanf("%lld%lld",&a,&b);
ll ans=0;
for(int i=1;i<sum;i++)
ans+=find(b,i)-find(a-1,i);
printf("%lld\n",ans);
return 0;
}