HDU 2089 不要62(数位DP)

Posted 负熵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 2089 不要62(数位DP)相关的知识,希望对你有一定的参考价值。

题意:求[n,m]内所有数字中不出现4也不出现连续62的数的个数。

输入:n m,多组数据,以0 0结尾。

输出:符合条件的数的个数。

限制:(0<n≤m<1000000) 时间:1000 ms 空间:32768 kB

分析:我们引入数位DP的应用范围:求出在给定区间[A,B]内,符合条件P(i)的数i的个数.条件P(i)一般与数的大小无关,而与 数的组成 有关.

           本题我们采用打表+递推的DP思路解题,空间复杂度比记忆化搜索略高,但便于理解。

#include <cstring>
#include <cstdio>
int dp[10][10];//dp[i][j]表示第i位为j时符合条件的数的个数 
void init(){//打表 
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for(int i=1;i<=7;i++)
    for(int j=0;j<10;j++)//枚举第i位可能出现的数
    for(int k=0;k<10;k++)//枚举第i-1位可能出现的数
    if(j!=4&&!(j==6&&k==2)) dp[i][j]+=dp[i-1][k];
}
int solve(int n){
    //printf("%d********%d*********%d\n",dp[4][2],dp[5][6],dp[5][7]); 
    int digit[10],len=0,ans=0;
    while(n>0){
        digit[++len]=n%10;
        n/=10;
    }
    digit[len+1]=0;
    for(int i=len;i;i--){//从高位到低位,每一位ans都加上所有符合条件的值,不重不漏 
        for(int j=0;j<digit[i];j++) if(j!=4&&!(digit[i+1]==6&&j==2)) ans+=dp[i][j];
        if(digit[i]==4||(digit[i]==2&&digit[i+1]==6)) break;//继续循环不可能再有符合题意的值,故直接跳出 
    }
    return ans;
}
int main(){
    int l,r;
    init();
    while(scanf("%d%d",&l,&r),l){
        printf("%d\n",solve(r+1)-solve(l));//区间相减,注意左闭右开 
    }
    return 0;
}

 

以上是关于HDU 2089 不要62(数位DP)的主要内容,如果未能解决你的问题,请参考以下文章

HDU2089 ------不要62(数位dp)

HDU 2089 不要62(数位DP)

hdu 2089 不要62数位dp

HDU 2089 不要62(数位dp入门)

HDU2089 不要62[数位DP]

hdu2089不要62(数位dp)