P2602 [ZJOI2010]数字计数(数位DP)

题目描述
给定两个正整数 aa 和 bb,求在 [a,b][a,b] 中的所有整数中,每个数码(digit)各出现了多少次。

输入格式
仅包含一行两个整数 a,ba,b,含义如上所述。

输出格式
包含一行十个整数,分别表示 0sim 90∼9 在 [a,b][a,b] 中出现了多少次。

#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
typedef long long ll;
ll L,R,f[maxn][maxn];
//f(i,j)表示当前到第i位,数字x出现j次的状态数
int a[maxn],len;
ll dfs (int pos,int st,int limit,int sum,int x) {
	if (pos<=0) {
		return sum;
	}
	if (!limit&&f[pos][sum]!=-1) return f[pos][sum];
	ll ans=0;
	ll k=limit?a[pos]:9;
	for (int i=0;i<=k;i++) {
		if (st&&i==0) {
			ans+=dfs(pos-1,st,limit&&i==k,sum,x);
		}
		else {
			ans+=dfs(pos-1,0,limit&&i==k,sum+(i==x),x);
		}
	}
	if (!limit&&!st) f[pos][sum]=ans;
	return ans;
}
ll solve (ll x,ll y) {
	len=0;
	while (x) {
		a[++len]=x%10;
		x/=10;
	}
	memset(f,-1,sizeof(f));
	return dfs(len,1,1,0,y);
}
int main () {
	cin>>L>>R;
	for (int i=0;i<=9;i++) cout<<solve(R,i)-solve(L-1,i)<<" ";
}
原文地址:https://www.cnblogs.com/zhanglichen/p/14590364.html