不要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;
}

 

posted @ 2013-03-28 16:39  小仪在努力~  阅读(297)  评论(0)    收藏  举报