记忆化搜索:
时间复杂度O(logn) 注意要开long long.
pos:当前数字最后pos位(从右往左pos位)
sum:表示当前数字(从右往左第pos位)前一共有多少要搜索的数字d
lead: 当前dp位之前一位是否有前导0
limit: 当前一位是否是最高位 是的话限制遍历的大小
比如324的百位 0~2 遍历i = 1~9
3 遍历i = 1~3.
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll cnt[13];
ll f[15][15];
ll dfs(int pos, ll sum, int lead, int limit, int d)
{
ll ans = 0;
if(pos == 0)return sum;
if(!limit && !lead && f[pos][sum] != -1)return f[pos][sum];
int res = (limit ? cnt[pos] : 9);
for(int i = 0;i <= res;i++)
{
if(lead && i == 0) ans += dfs(pos - 1, sum, true, limit && i == res, d);
else if(i != d)ans += dfs(pos - 1, sum, false, limit && i == res,d );
else if(i == d) ans += dfs(pos - 1, sum + 1, false, limit && i == res, d);
}
if(!limit && !lead)f[pos][sum] = ans;
return ans;
}
ll isg(ll x, int i)
{
int len = 0;
while(x)
{
cnt[++len] = x % 10;
x /= 10;
}
memset(f, -1, sizeof f);
ll ans = dfs(len, 0, 1, 1, i);
return ans;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
ll a, b;
cin >> a >> b;
for(int i = 0;i <= 9;i++)cout << isg(b, i) - isg(a - 1, i) << " ";
return 0;
}