luogu P2602 [ZJOI2010]数字计数 数位dp

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long ll;
const int N = 15;
ll f[N][2][N][2];
int num[N];
ll dfs(int len, bool limit, int sum, bool zero, int d)
{
	ll ret = 0;
	if (len == 0)
		return sum;
	if (f[len][limit][sum][zero] != -1)
		return f[len][limit][sum][zero];
	int up=limit?num[len]:9;
	for (int i = 0; i <= up; i ++)
		ret += dfs(len-1, limit && i==num[len], sum+((!zero || i) && (i==d)), zero && (i == 0), d);
	f[len][limit][sum][zero] = ret;
	return ret;
}
ll solve(ll x, int d)
{
	int len = 0;
	while (x)
	{
		num[++ len] = x%10;
		x /= 10;
	} //数字转数位
	memset(f, -1, sizeof f); //初始化
	return dfs(len, 1, 0, 1, d);
}
int main()
{
	ll a, b; 
	cin>>a>>b; 
	for (int i = 0; i < 10; i ++)
		cout<<solve(b, i)-solve(a-1, i)<<" ";
	return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12833748.html