AcWing338 计数问题(数位dp)

一道经典的数位dp,我们想要知道各个数分别是多少,不如通过枚举,每次判断一个数。

这题需要判断前导0,我们是否判断前导0的原因就是要看这个0会不会对答案产生影响

这题我们要求0的个数,显然必须判断前导0,例如windy数,前后差值的关系,显然也要判断

但是像数字游戏这类问题就不需要判断,因为不影响

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
string l,r,s;
int f[20][11][2][2];
int x;
int len;
int dfs(int cur,int n1,int flag,int g){
    if(cur==len)
    return n1;
    auto &a=f[cur][n1][flag][g];
    if(a!=-1)
    return a;
    int v=9;
    if(flag)
    v=s[cur]-'0';
    int i;
    int ans=0;
    for(i=0;i<=v;i++){
        if(g){
            if(!i)
            ans+=dfs(cur+1,0,flag&&(i==v),1);
            else
            ans+=dfs(cur+1,n1+(i==x),flag&&(i==v),0);
        }
        else
            ans+=dfs(cur+1,n1+(i==x),flag&&(i==v),0);
    }
    return a=ans;
}
int solve(string t){
    s=t;
    len=s.size();
    memset(f,-1,sizeof f);
    return dfs(0,0,1,1);
}
int check(string s){
    int ans=0;
    int i;
    for(i=0;i<s.size();i++){
        if(s[i]-'0'==x)
        ans++;
    }
    return ans;
}
int main(){
    int i;
    while(cin>>l>>r){
        if(l=="0"&&r=="0")
        break;
        if(l.length()>r.length()||(l.length()==r.length()&&l>r))
        swap(l,r);
        int ans=0;
        for(x=0;x<=9;x++){
            ans=solve(r)-solve(l)+check(l);
            cout<<ans<<" ";
        }
        cout<<endl;
    }
}
View Code

 

posted @ 2020-04-14 15:01  朝暮不思  阅读(174)  评论(0编辑  收藏  举报