数位DP,枚举数位和,然后用
f
[
p
o
s
]
[
r
e
s
]
[
n
o
w
]
[
l
i
m
i
t
]
f[pos][res][now][limit]
f[pos][res][now][limit]记录还需要填
p
o
s
pos
pos个数,当前余数为
r
e
s
res
res,当前数位和为
n
o
w
now
now,是否有限制的方案数。
注意每枚举一次
s
u
m
sum
sum都要把
f
f
f清空。因为
s
u
m
sum
sum一直在变。
一开始不小心把 f f f数组中 n o w now now写成 s u m sum sum了。谢谢 G S J GSJ GSJ神仙。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int a[20],sum;ll l,r;
ll f[20][165][165][2];
inline ll dp(int pos,int res,int now,bool limit,ll ans=0){
if(now>sum) return 0;
if(!pos) return (now==sum)&&(!res);
if(~f[pos][res][now][limit]) return f[pos][res][now][limit];
int up=limit?a[pos]:9;
for(int i=0;i<=up;++i)
ans+=dp(pos-1,(res*10+i)%sum,now+i,limit&&(i==up));
return f[pos][res][now][limit]=ans;
}
inline ll calc(ll x,int pos=0,ll tot=0){
while(x) a[++pos]=x%10,x/=10;
for(sum=1;sum<=(9*pos);++sum){
memset(f,-1,sizeof(f));
tot+=dp(pos,0,0,true);
}return tot;
}
int main(){
memset(f,-1,sizeof(f));
cin>>l>>r;cout<<(calc(r)-calc(l-1));
}