[BZOJ] 1833: [ZJOI2010]count 数字计数
用DFS实现的数位dp
设当前做到第pos位,所求数字为num,出现了sum次,允许/不允许前导0,保证/未保证随意填的状态,即可DFS
坚信数位DP是不会卡时间的,慢点好写
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long ll;
inline ll rd(){
ll ret=0ll,f=1ll;char c;
while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
while(isdigit(c))ret=ret*10ll+c-'0',c=getchar();
return ret*f;
}
ll L,R;
ll f[20][20][20];
int a[31];
ll dfs(int pos,int num,ll sum,int zero,int lim){
if(pos==0)return sum;
if(!zero&&!lim&&f[pos][num][sum]!=-1) return f[pos][num][sum];
ll ret=0ll;
int up=lim?a[pos]:9;
if(!zero||pos==1)ret+=dfs(pos-1,num,sum+(num==0),0,lim&&a[pos]==0);
else ret+=dfs(pos-1,num,sum,1,lim&&a[pos]==0);
for(int i=1;i<=up;i++)ret+=dfs(pos-1,num,sum+(num==i),0,lim&&a[pos]==i);
if(!zero&&!lim)f[pos][num][sum]=ret;
return ret;
}
ll solve(ll x,int num){
if(x<0) return 0;
if(x==0) return num==0;
int top=0;
while(x){
a[++top]=x%10;
x/=10;
}
return dfs(top,num,0,1,1);
}
int main(){
L=rd();R=rd();
memset(f,-1,sizeof(f));
for(int i=0;i<=9;i++)printf("%lld ",solve(R,i)-solve(L-1,i));
return 0;
}
本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9726615.html