不要62

/*区间求不含有62和4的数量,我的第一道数位DP*/

#include<stdio.h>

#include<iostream>

#include<cstring>

using namespace std;

int dp[20][3];

int cal(int key)

{

    int digit[20],len=0,ans=0;

    memset(digit,0,sizeof(digit));

    int ok=key;

    while(ok)

    {

        digit[++len]=ok%10;

        ok/=10;

    }

    bool flag=false;

    for(int i=len; i>0; --i)

    {

        ans+=dp[i-1][2]*digit[i];

        if(flag) ans+=dp[i-1][0]*digit[i]; //如果前面出现过4,或者62,则不含不吉利数字的数量得乘本位

        else

        {

            if(digit[i]>4) ans+=dp[i-1][0];//如果本位大于4,不含不吉利数字的数量得乘本位,因为前面的数位是确定的

            if(digit[i]>6) ans+=dp[i-1][1]; //如果本位大于6,前一位带2不含不吉利数字的数量乘本位

            if(digit[i+1]==6&&digit[i]>2) //如果本位大于2,而且前一位等于6,i长度以2开头的含不吉利数字的数量乘于本位

            ans+=dp[i][1];

        }

        if(digit[i]==4||(digit[i+1]==6&&digit[i]==2))//如果出现符合条件的前面的数,标志置1

        flag=true;

    }

    return key-ans;

}

int main()

{

    memset(dp,0,sizeof(dp));

    int l,r,i;

    dp[0][0]=1; //初始化条件必须为1,important

    for(i=1; i<10; ++i)

    {

        dp[i][0]=dp[i-1][0]*9-dp[i-1][1]; //dp[i][0]不含有不吉利数字的个数

        dp[i][1]=dp[i-1][0];              //dp[i][1]以2开头不含不吉利数字的个数

        dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1]; //含有不吉利数字的个数

    }

    while(cin>>l>>r)

    {

        if(l==0&&r==0) break;

        //cout<<cal(r+1)<<" "<<cal(l)<<endl;

        printf("%d\n",cal(r+1)-cal(l));

    }

    return 0;

}

 

你可能感兴趣的:(不要62)