Description
题解
-
1
0
100
10^{100}
10100的数据明示算法:数位DP
- 令状态
d
p
[
x
]
[
d
]
[
l
]
[
s
]
dp[x][d][l][s]
dp[x][d][l][s]
-
x
x~
x :搜到位置
-
d
d~
d :
A
A
A前面位数和
−
B
-B
−B前面位数和(防负数偏移
1000
1000
1000)
-
l
l~
l :limit,当前位之前
B
B
B是否等于
N
N
N,反映限制
B
≤
N
B\leq N
B≤N
-
s
s~
s :当前位之前
A
A
A是否等于
B
B
B,反映限制
A
≤
B
A\leq B
A≤B
#include <cstdio>
#include <cstring>
const int N=110,mod=1e9+7;
using namespace std;
int n,digit[N],dp[N][N*20][2][2];
char s[N];
int dfs(int x,int d,bool l,bool s){
if(!x) return d>1000;
if(~dp[x][d][l][s]) return dp[x][d][l][s];
int ret=0,lim=l?digit[x]:9;
for(int i=0;i<=lim;i++)
for(int j=0;j<=(s?i:9);j++)
ret=(ret+dfs(x-1,d+j-i,l&(digit[x]==i),s&(i==j)))%mod;
return dp[x][d][l][s]=ret;
}int main(){
memset(dp,-1,sizeof(dp));
scanf("%s",s),n=strlen(s);
for(int i=0;i<n;i++) digit[n-i]=s[i]-'0';
printf("%d\n",dfs(n,1000,1,1));
}