【数位DP】[CQOI2016]手机号码

题目描述

这里写图片描述

分析

这题的要求的是组成该数的数字满足一些条件的数,并且看数据范围,果断锁定数位DP。
考场上我写记忆化搜索的把自己搞晕了,然后果断改写递推版。
f表示<=n的满足条件的电话号码,定义状态7维

f[ff][i][j][f1][f2][f3][l]  //是否比n小  当前是第几位  几个连续  是否3个连续   是否有8  是否有4 当前选择的数字是什么

状态转移十分复杂(写着复杂),但是思维难度不大,只要有耐心就能写对。
具体方程看我的代码。

ans=cal(r)cal(l1)

代码

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long LL;
LL f[2][20][5][2][2][2][10];  //第几位  几个连续  是否3个连续   8  4
LL l,r;
int d[20],len;
template<class T>
void Read(T &x){
    char c;
    while(c=getchar(),c!=EOF)
        if(c>='0'&&c<='9'){
            x=c-'0';
            while(c=getchar(),c>='0'&&c<='9')
                x=x*10+c-'0';
            ungetc(c,stdin);
            return;
        }
}/*
LL dfs(int i,int j,bool tr,bool et,bool fu,int d,bool ff){
    if(et&&fu)
        return 0;
    if(!i){
    }
    if(!ff&&~f[i][j][tr][et][fu])
        return f[i][j][tr][et][fu];
    LL ret=0;
    int j,mx=ff?d[i-1]:9;
    if(d==8)
        if(j==2){
            ret=dfs(i-1,j-1,tr,et,fu,8,0);
        }
}*/
void dp(){
    int i,j,k,l;
    for(i=0;i<=9;i++){
        if(i==8)
            f[0][0][0][0][1][0][i]=f[1][0][0][0][1][0][i]=1;
        else if(i==4)
            f[0][0][0][0][0][1][i]=f[1][0][0][0][0][1][i]=1;
        else
            f[0][0][0][0][0][0][i]=f[1][0][0][0][0][0][i]=1;
    }     //第几位  几个连续  是否3个连续   8  4
    for(i=1;i<=len;i++){
        for(j=0;j<=9;j++){
            for(k=0;k<=9;k++)
                if(j!=k){
                    if(j==8){
                        for(l=1;l<=2;l++)
                            f[0][i][1][0][1][0][j]+=f[0][i-1][l][0][0][0][k]+f[0][i-1][l][0][1][0][k];
                        f[0][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][k]+f[0][i-1][0][1][0][0][k];
                    }
                    else if(j==4){
                        for(l=1;l<=2;l++)
                            f[0][i][1][0][0][1][j]+=f[0][i-1][l][0][0][1][k]+f[0][i-1][l][0][0][0][k];
                        f[0][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][k]+f[0][i-1][0][1][0][0][k];  
                    }
                    else{
                        for(l=1;l<=2;l++){
                            f[0][i][1][0][1][0][j]+=f[0][i-1][l][0][1][0][k];
                            f[0][i][1][0][0][1][j]+=f[0][i-1][l][0][0][1][k];
                            f[0][i][1][0][0][0][j]+=f[0][i-1][l][0][0][0][k];
                        }
                        f[0][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][k];
                        f[0][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][k];
                        f[0][i][0][1][0][0][j]+=f[0][i-1][0][1][0][0][k];
                    }
                }
                else{
                    if(j==8){
                        for(l=1;l<=2;l++)
                            f[0][i][l][0][1][0][j]+=f[0][i-1][l-1][0][1][0][j];
                        f[0][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][j]+f[0][i-1][2][0][1][0][j];
                    }
                    else if(j==4){
                        for(l=1;l<=2;l++)
                            f[0][i][l][0][0][1][j]+=f[0][i-1][l-1][0][0][1][j];
                        f[0][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][j]+f[0][i-1][2][0][0][1][j];
                    }
                    else{
                        for(l=1;l<=2;l++){
                            f[0][i][l][0][1][0][j]+=f[0][i-1][l-1][0][1][0][j];
                            f[0][i][l][0][0][1][j]+=f[0][i-1][l-1][0][0][1][j];
                            f[0][i][l][0][0][0][j]+=f[0][i-1][l-1][0][0][0][j];
                        }
                        f[0][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][j]+f[0][i-1][2][0][1][0][j];
                        f[0][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][j]+f[0][i-1][2][0][0][1][j];
                        f[0][i][0][1][0][0][j]+=f[0][i-1][0][1][0][0][j]+f[0][i-1][2][0][0][0][j];
                    }
                }
        }
        j=d[i];
        for(k=0;k<d[i-1];k++){
            if(d[i]!=k){
                if(d[i]==8){
                    for(l=1;l<=2;l++)
                        f[1][i][1][0][1][0][d[i]]+=f[0][i-1][l][0][1][0][k]+f[0][i-1][l][0][0][0][k];
                    f[1][i][0][1][1][0][d[i]]+=f[0][i-1][0][1][1][0][k]+f[0][i-1][0][1][0][0][k];
                }
                else if(d[i]==4){
                    for(l=1;l<=2;l++)
                        f[1][i][1][0][0][1][d[i]]+=f[0][i-1][l][0][0][1][k]+f[0][i-1][l][0][0][0][k];
                    f[1][i][0][1][0][1][d[i]]+=f[0][i-1][0][1][0][1][k]+f[0][i-1][0][1][0][0][k];
                }
                else{
                    for(l=1;l<=2;l++){
                        f[1][i][1][0][0][1][d[i]]+=f[0][i-1][l][0][0][1][k];
                        f[1][i][1][0][1][0][d[i]]+=f[0][i-1][l][0][1][0][k];
                        f[1][i][1][0][0][0][d[i]]+=f[0][i-1][l][0][0][0][k];
                    }
                    f[1][i][0][1][0][1][d[i]]+=f[0][i-1][0][1][0][1][k];
                    f[1][i][0][1][1][0][d[i]]+=f[0][i-1][0][1][1][0][k];
                    f[1][i][0][1][0][0][d[i]]+=f[0][i-1][0][1][0][0][k];
                }
            }
            else{
                if(d[i]==8){
                    for(l=1;l<=2;l++)
                        f[1][i][l][0][1][0][j]+=f[0][i-1][l-1][0][1][0][j];
                    f[1][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][d[i]]+f[0][i-1][2][0][1][0][d[i]];
                }
                else if(d[i]==4){
                    for(l=1;l<=2;l++)
                        f[1][i][l][0][0][1][j]+=f[0][i-1][l-1][0][0][1][j];
                    f[1][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][d[i]]+f[0][i-1][2][0][0][1][d[i]];
                }
                else{
                    for(l=1;l<=2;l++){
                        f[1][i][l][0][1][0][j]+=f[0][i-1][l-1][0][1][0][j];
                        f[1][i][l][0][0][1][j]+=f[0][i-1][l-1][0][0][1][j];
                        f[1][i][l][0][0][0][j]+=f[0][i-1][l-1][0][0][0][j];
                    }
                    f[1][i][0][1][1][0][j]+=f[0][i-1][0][1][1][0][d[i]]+f[0][i-1][2][0][1][0][d[i]];
                    f[1][i][0][1][0][1][j]+=f[0][i-1][0][1][0][1][d[i]]+f[0][i-1][2][0][0][1][d[i]];
                    f[1][i][0][1][0][0][j]+=f[0][i-1][0][1][0][0][d[i]]+f[0][i-1][2][0][0][0][d[i]];
                }
            }
        }
        if(d[i]!=k){
            if(d[i]==8){
                for(l=1;l<=2;l++)
                    f[1][i][1][0][1][0][d[i]]+=f[1][i-1][l][0][1][0][k]+f[1][i-1][l][0][0][0][k];
                f[1][i][0][1][1][0][d[i]]+=f[1][i-1][0][1][1][0][k]+f[1][i-1][0][1][0][0][k];
            }
            else if(d[i]==4){
                for(l=1;l<=2;l++)
                    f[1][i][1][0][0][1][d[i]]+=f[1][i-1][l][0][0][1][k]+f[1][i-1][l][0][0][0][k];
                f[1][i][0][1][0][1][d[i]]+=f[1][i-1][0][1][0][1][k]+f[1][i-1][0][1][0][0][k];
            }
            else{
                for(l=1;l<=2;l++){
                    f[1][i][1][0][0][1][d[i]]+=f[1][i-1][l][0][0][1][k];
                    f[1][i][1][0][1][0][d[i]]+=f[1][i-1][l][0][1][0][k];
                    f[1][i][1][0][0][0][d[i]]+=f[1][i-1][l][0][0][0][k];
                }
                f[1][i][0][1][0][1][d[i]]+=f[1][i-1][0][1][0][1][k];
                f[1][i][0][1][1][0][d[i]]+=f[1][i-1][0][1][1][0][k];
                f[1][i][0][1][0][0][d[i]]+=f[1][i-1][0][1][0][0][k];
            }
        }
        else{
            if(d[i]==8){
                for(l=1;l<=2;l++)
                    f[1][i][l][0][1][0][d[i]]+=f[1][i-1][l-1][0][1][0][d[i]];
                f[1][i][0][1][1][0][d[i]]+=f[1][i-1][0][1][1][0][d[i]]+f[1][i-1][2][0][1][0][d[i]];
            }
            else if(d[i]==4){
                for(l=1;l<=2;l++)
                        f[1][i][l][0][0][1][d[i]]+=f[1][i-1][l-1][0][0][1][d[i]];
                f[1][i][0][1][0][1][d[i]]+=f[1][i-1][0][1][0][1][d[i]]+f[1][i-1][2][0][0][1][d[i]];
            }
            else{
                for(l=1;l<=2;l++){
                    f[1][i][l][0][1][0][d[i]]+=f[1][i-1][l-1][0][1][0][d[i]];
                    f[1][i][l][0][0][1][d[i]]+=f[1][i-1][l-1][0][0][1][d[i]];
                    f[1][i][l][0][0][0][d[i]]+=f[1][i-1][l-1][0][0][0][d[i]];
                }
                f[1][i][0][1][1][0][d[i]]+=f[1][i-1][0][1][1][0][d[i]]+f[1][i-1][2][0][1][0][d[i]];
                f[1][i][0][1][0][1][d[i]]+=f[1][i-1][0][1][0][1][d[i]]+f[1][i-1][2][0][0][1][d[i]];
                f[1][i][0][1][0][0][d[i]]+=f[1][i-1][0][1][0][0][d[i]]+f[1][i-1][2][0][0][0][d[i]];
            }
        }
    }
}
LL cal(LL n){
    len=0;
    LL ret=0;
    while(n){
        d[++len]=n%10;
        n/=10;
    }
    d[0]=9;
    if(len<11)
        d[++len]=0;
    memset(f,0,sizeof f);
    dp();
    for(int i=0;i<d[len];i++)
        ret+=f[0][len][0][1][0][0][i]+f[0][len][0][1][0][1][i]+f[0][len][0][1][1][0][i];
    ret+=f[1][len][0][1][0][0][d[len]]+f[1][len][0][1][0][1][d[len]]+f[1][len][0][1][1][0][d[len]];
    return ret;
//  for(i=0;i<=mx;i++)
    //  return dfs(len,0,1,0,1,1)+dfs(len,0,1,1,0,1);
}
int main()
{
    Read(l),Read(r);
    printf("%lld\n",cal(r)-cal(l-1));
}
posted @ 2016-04-10 20:47  outer_form  阅读(174)  评论(0编辑  收藏  举报