状态:
d
p
[
i
]
[
j
]
[
k
]
[
l
]
:
dp[i][j][k][l]:
dp[i][j][k][l]:搜到第i位,目前出现搜到的数出现digit次数为i,上界是否触顶k,有无前导零l
目标:
(
s
u
m
[
r
]
−
s
u
m
[
l
−
1
]
)
(
s
u
m
[
i
]
代
表
1
i
内
的
所
有
合
法
数
的
个
数
)
(sum[r]-sum[l-1])(sum[i]代表1~i内的所有合法数的个数)
(sum[r]−sum[l−1])(sum[i]代表1i内的所有合法数的个数)
边界: 没有
合法判断: 条件转移合法判断
记忆化转移无需预处理
attention: 主要是出现次数这种新状态
双倍经验: 记忆化细节少
@author: jasonleft 记忆化数位
#include<bits/stdc++.h>#include<bits/extc++.h>#define _rep(i, a, b) for (int i = (a); i <= (b); ++i)#define _rev(i, a, b) for (int i = (a); i >= (b); --i)#define _for(i, a, b) for (int i = (a); i < (b); ++i)#define _rof(i, a, b) for (int i = (a); i > (b); --i)#define ll long long#define db double#define oo 0x3f3f3f3f#define eps 0.00001#define all(x) x.begin(), x.end()#define met(a, b) memset(a, b, sizeof(a))#define id(x) ((x + 8))#define bin(x) cerr << #x << " is " << bitset<8>(x) << endl#define what_is(x) cerr << #x << " is " << x << endl#define lowbit(x) x &(-x)usingnamespace std;constint maxn =1002;constint mod =9999973;
ll dp[maxn][maxn][2][2], cnt, a[maxn], l, r;
ll dfs(int cur,int sum,bool lim,bool zeros,int digit){if(cur ==0)return sum;
ll &t = dp[cur][sum][lim][zeros];if(~t)return t;
t =0;_rep(i,0,9){if(!lim || i <= a[cur])
t +=dfs(cur -1,(zeros && i ==0?0: sum +(i == digit)), lim && i == a[cur], zeros && i ==0, digit);}return t;}
ll __ask(int __,int id){met(dp,-1),met(a,0);
cnt =0;while(__)
a[++cnt]= __ %10, __ /=10;returndfs(cnt,0,1,1, id);}signedmain(){
cin >> l >> r;_rep(i,0,9)
cout
<<__ask(r, i)-__ask(l -1, i)<<" ";}