hdu3555 数位dp

来源:互联网 发布:redis数据库设计java 编辑:程序博客网 时间:2024/06/05 09:04

  dp[i][0]表示没有“49”的最高位不为0个数,dp[i][1]表示最高位为“9”且没有“49”,dp[i][2]表示含有“49”且最高位不为0,i表示i位

  转移方程:

memset(dp[0],0,sizeof(dp[0]));    dp[1][0]=10; //without "49"    dp[1][1]=1; //start with "9" without "49"    dp[1][2]=0; //hava "49"    for(int i=2;i<25;++i){        dp[i][0]=dp[i-1][1]*8+(dp[i-1][0]-dp[i-1][1])*9;        dp[i][1]=dp[i-1][0];        dp[i][2]=dp[i-1][2]*9+dp[i-1][1];        for(int j=1;j<i-1;++j){            dp[i][0]+=dp[j][0]*9;            dp[i][1]+=dp[j][0];            dp[i][2]+=9*dp[j][2];        }    }


AC代码:

#include<cstdio>#include<cstring>#include<cmath>const int maxn=25;typedef long long LL;LL dp[maxn][3],d[maxn];LL N;void solve(){    memset(dp[0],0,sizeof(dp[0]));    dp[1][0]=10; //without "49"    dp[1][1]=1; //start with "9" without "49"    dp[1][2]=0; //hava "49"    for(int i=2;i<25;++i){        dp[i][0]=dp[i-1][1]*8+(dp[i-1][0]-dp[i-1][1])*9;        dp[i][1]=dp[i-1][0];        dp[i][2]=dp[i-1][2]*9+dp[i-1][1];        for(int j=1;j<i-1;++j){            dp[i][0]+=dp[j][0]*9;            dp[i][1]+=dp[j][0];            dp[i][2]+=9*dp[j][2];        }    }    d[0]=0;    for(int i=1;i<25;++i)        d[i]=d[i-1]+dp[i][2];}LL print(LL n){    int a[maxn],len=1;    while(n>0){        a[len++]=n%10;        n/=10;    }    LL ans=0;    for(int i=len-1;i>=1;--i){        if(i==len-1){            if(a[i]>4) ans+=dp[i-1][1];            ans+=d[i-1]*a[i];        }        else{            if(a[i]>4) ans+=dp[i-1][1];            ans+=d[i-1]*a[i];            if(a[i+1]==4&&a[i]==9){                LL p=0;               for(int j=i-1;j>0;--j){                    p=p*10+a[j];               }               ans+=p+1;               break;            }        }    }    return ans;}int main(){    solve();    int T;    scanf("%d",&T);    while(T--){        scanf("%lld",&N);        printf("%lld\n",print(N));    }    return 0;}

如有不当之处欢迎指出!

0 0