【入门计数类问题/数位DP模板】来自于唐老师rgnoH

模板太优秀了,对于入门的计数类问题,都不用思考,暴力定状态暴力套模板0ms轻松过

stQ 膜rgnoH 膜rgnoH Orz

样例:CQOI2015电话号码

#include
using namespace std;
typedef long long ll;

ll t1,t2,m=11,num[20],l,r,f[20][10][10][2][2][2][2];

ll Dfs(int cur,int pre,int def,int same,int eight,int four,int lim){
    if(f[cur][pre][def][same][eight][four][lim]!=-1)return f[cur][pre][def][same][eight][four][lim];
    if(cur==m+1){
        if(same&&!(eight&&four))return 1;
        return 0;
    }
    ll Ans=0;
    int t,a,b,c,d;
    t=lim?num[cur]:9;
    for(int i=(cur>1?0:1);i<=t;i++){
        if(i==pre&&i==def)a=1;else a=same;
        if(i==8)b=1;else b=eight;
        if(i==4)c=1;else c=four;
        if(lim&&i==num[cur])d=1;else d=0;
        if(!(b&&c))Ans+=Dfs(cur+1,i,pre,a,b,c,d);
    }
    return f[cur][pre][def][same][eight][four][lim]=Ans;
}

int main(){
    scanf("%lld%lld",&t1,&t2);

    memset(f,-1,sizeof(f));
    if(t1==10000000000)l=0;
    else{
        t1--;
        for(int i=1;i<=m;i++)num[m-i+1]=t1%10,t1/=10;
        l=Dfs(1,0,0,0,0,0,1);
    }

    memset(f,-1,sizeof(f));
    for(int i=1;i<=m;i++)num[m-i+1]=t2%10,t2/=10;
    r=Dfs(1,0,0,0,0,0,1);
    printf("%lld",r-l);
}

你可能感兴趣的:(dp,数位DP)