ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

数位dp

状态可表示为f(位数,最高位,最长相同数字前缀长度(大于3取3),是否有连续三位相同,是否出现4,是否出现8)共6维

#include<cstdio>
typedef long long lint;
lint f[15][10][3][2][2][2];
lint L,R;
int stk[16],p=0;
lint calc(lint x){
    p=0;
    lint ans=0,x0=x;
    while(x)stk[++p]=x%10,x/=10;
    for(int i=1;i<p;i++){
        for(int j=1;j<10;j++){
            for(int a=0;a<3;a++)
            ans+=f[i][j][a][1][0][0]+f[i][j][a][1][0][1]+f[i][j][a][1][1][0];
        }
    }
    for(int i=1;i<stk[p];i++){
        for(int a=0;a<3;a++)
        ans+=f[p][i][a][1][0][0]+f[p][i][a][1][0][1]+f[p][i][a][1][1][0];
    }
    int p1=stk[p],p2=0;
    int d4=p1==4,d8=p1==8,l3=0;
    for(int i=p-1;i;--i){
        for(int j=0;j<stk[i];j++){
            for(int a=0;a<3;a++){
                ans+=f[i][j][a][1][0][0];
                if(!d4)ans+=f[i][j][a][1][0][1];
                if(!d8)ans+=f[i][j][a][1][1][0];
                if(l3){
                    ans+=f[i][j][a][0][0][0];
                    if(!d4)ans+=f[i][j][a][0][0][1];
                    if(!d8)ans+=f[i][j][a][0][1][0];
                }
            }
            if(l3)continue;
            if(p1==j){
                ans+=f[i][j][1][0][0][0];
                if(!d4)ans+=f[i][j][1][0][0][1];
                if(!d8)ans+=f[i][j][1][0][1][0];
                if(p1==p2){
                    ans+=f[i][j][0][0][0][0];
                    if(!d4)ans+=f[i][j][0][0][0][1];
                    if(!d8)ans+=f[i][j][0][0][1][0];
                }
            }
        }
        if(p1==p2&&p1==stk[i])l3=1;
        p2=p1;p1=stk[i];
        if(p1==4){
            if(d8)break;
            d4=1;
        }
        if(p1==8){
            if(d4)break;
            d8=1;
        }
    }
    return ans;
}
int main(){
    for(int i=0;i<10;i++)f[1][i][0][0][i==4][i==8]=1;
    for(int i=2;i<=12;i++){
        for(int j=0;j<10;j++){
            for(int k=0;k<10;k++){
                for(int d4=0;d4<2;d4++){
                    for(int d8=0;d8<2;d8++){
                        if(j!=k){
                            for(int w=0;w<3;w++)
                            f[i][j][0][0][d4||j==4][d8||j==8]+=f[i-1][k][w][0][d4][d8],
                            f[i][j][0][1][d4||j==4][d8||j==8]+=f[i-1][k][w][1][d4][d8];
                        }else{
                            f[i][j][1][0][d4||j==4][d8||j==8]+=f[i-1][k][0][0][d4][d8];
                            f[i][j][1][1][d4||j==4][d8||j==8]+=f[i-1][k][0][1][d4][d8];
                            f[i][j][2][1][d4||j==4][d8||j==8]+=f[i-1][k][1][0][d4][d8];
                            f[i][j][2][1][d4||j==4][d8||j==8]+=f[i-1][k][1][1][d4][d8];
                            f[i][j][2][1][d4||j==4][d8||j==8]+=f[i-1][k][2][1][d4][d8];
                        }
                    }
                }
            }
        }
    }
    scanf("%lld%lld",&L,&R);
    printf("%lld",calc(R+1)-calc(L));
    return 0;
}

 

posted on 2016-04-11 20:13  nul  阅读(380)  评论(0编辑  收藏  举报