数位DP(不要62)

传送门

#include<bits/stdc++.h>
using namespace std;
int dp[10][10],d[10];
void init(){
    dp[0][0]=1;
    for(int i=1;i<7;i++){
        for(int j=0;j<=9;j++){
            for(int k=0;k<=9;k++){
                if((j!=4)&&!(j==6&&k==2)){
                    dp[i][j]+=dp[i-1][k];
                }
            }
        }
    }
}
int S(int x){
    int len=0;
    int ans=0;
    while(x){
        d[++len]=x%10;
        x/=10;
    }
    d[len+1]=0;
    for(int i=len;i>=1;i--){
        for(int j=0;j<d[i];j++){
            if(j!=4&&!(d[i+1]==6&&j==2)){
                ans+=dp[i][j];
            }
        }
        if(d[i]==4||(d[i+1]==6&&d[i]==2)){
            break;
        }
    }
    return ans;
}
int main()
{
    init();
    int n,m;
    while(~scanf("%d%d",&n,&m),(n||m)){
        int ans=S(m+1)-S(n);
        printf("%d\n",ans);
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
int dp[10][3]={0},d[10]={0};
void init(){
    dp[0][0]=1;
    for(int i=1;i<=8;i++){
        dp[i][0]=dp[i-1][0]*9-dp[i-1][1];
        dp[i][1]=dp[i-1][0];
        dp[i][2]=dp[i-1][2]*10+dp[i-1][1]+dp[i-1][0];
    }
}
int S(int x){
    int T=x,len=0;
    int flag=0;
    int cnt=0;
    for(;x;d[++len]=x%10,x/=10);
    d[len+1]=0;
    for(int i=len;i>0;i--){

        cnt +=( dp[i-1][2] * d[i] );

        if(flag){
            cnt += (dp[i-1][0]*d[i]);
        }else{
            if(d[i]>4)  cnt+=dp[i-1][0];

            if(d[i]>6)  cnt+=dp[i-1][1];

            if(d[i+1]==6&&d[i]>2)  cnt+=dp[i][1];
        }
        if(d[i]==4||(d[i+1]==6&&d[i]==2)){
                flag=1;
        }
    }
    return T-cnt;
}
int main()
{
    init();
    int n,m;
    while(~scanf("%d%d",&n,&m),(n||m)){
        int ans = S(m+1)-S(n);
        printf("%d\n",ans);
    }
    return 0;
}
#include<bits/stdc++.h>
using namespace std;
int a[10];
int dp[20][2];
int dfs(int pos,int pre,int sta,int limit){
    if(pos==-1) return 1;
    if(!limit&&dp[pos][sta]!=-1) return dp[pos][sta];
    int up=(limit?a[pos]:9);
    int tmp=0;
    for(int i=0;i<=up;i++){
        if( pre==6   && i==2) continue;
        if(i==4)    continue;
        tmp+=dfs(pos-1,i,i==6,limit&&i==a[pos]);
    }
    if(!limit)
        dp[pos][sta]=tmp;
    return tmp;
}
int solve(int x){
    int pos=0;
    while(x){
        a[pos++]=x%10;
        x/=10;
    }
    return dfs(pos-1,-1,1,true);
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m),(n||m)){
        memset(dp,-1,sizeof(dp));
        printf("%d\n",solve(m)-solve(n-1));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Z_sea/article/details/81190105
今日推荐