【HDU.2089 题意】

不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。

【解题方法】数位DP。dp[i][j]代表当前i位并且首位为j的最大方案!

【AC code】

#include<cstdio>
#include<cstring>
#include <iostream>
#define M 10
int dp[M][M];
using namespace std;
void init()
{
    dp[0][0]=1;
    for(int i=1; i<=6; i++)
    {
        for(int j=0; j<=9; j++)//枚举第i位
        {
            for(int k=0; k<=9; k++)//枚举第i-1位
            {
                if(j==4||k==4) continue;
                if(k==2&&j==6) continue;
                //if(k==6&&j==2) continue;
                dp[i][j]+=dp[i-1][k];
            }
        }
    }
}
int num[10];
int solve(int n)
{
    int t=0;
    memset(num,0,sizeof(num));
    while(n)
    {
        num[++t]=n%10;
        n/=10;
    }
    int ans=0;
    for(int i=t; i>=1; i--)
    {

        for(int j=0; j<num[i]; j++)
        {
            if(j==4) continue;
            if(num[i+1]==6&&j==2) continue;
            ans+=dp[i][j];
        }
        if(num[i]==4||(num[i]==2&&num[i+1]==6)) break;
    }
    return ans;
}

int main()
{
    int l,r;
    init();
    while(scanf("%d%d",&l,&r)!=EOF)
    {
        if(l==0&&r==0) break;
        printf("%d\n",solve(r+1)-solve(l));
    }

}

【HDU.3555】 实际上就是上个题的逆过程了。

【AC code】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define M 30
#define ll __int64
ll dp[M][10];
void init()
{
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for(int i=1; i<30; i++)
    {
        for(int j=0; j<=9; j++)//第i位
        {
            for(int k=0; k<=9; k++)//第i-1位
            {
                if(j==4&&k==9) continue;
                dp[i][j]+=dp[i-1][k];
            }
        }
    }
}
int num[25];
ll solve(ll n)
{
    int t=0;
    memset(num,0,sizeof(num));
    while(n)
    {
        num[++t]=n%10;
        n/=10;
    }
    ll ans=0;
    for(int i=t; i>=1; i--)
    {
        for(int j=0; j<num[i]; j++)
        {
            if(j==9&&num[i+1]==4) continue;
            ans+=dp[i][j];
        }
        if(num[i]==9&&num[i+1]==4) break;
    }
    return ans;
}
int main()
{
    int T;
    ll n;
    scanf("%d",&T);
    init();
    while(T--)
    {
        scanf("%I64d",&n);
        printf("%I64d\n",(ll)(n+1)-solve(n+1));
    }
}