您的位置:首页 > 其它

hdu2089 不要62 数位dp

2015-01-27 22:30 323 查看
题意:给定一个区间,求这个区间内不含4和62(6,2连续)的数的个数。

分析:数位dp,此题可由低位递推高位,dp[i][0]表示i位数无不吉利数字,dp[i][1]表示i位数无不吉利数字且最高位为2,dp[i][2]表示i位数有不吉利数字。

#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ULL;
typedef long long LL;
const int maxn=100005;
int n,m;
int dp[10][3];
int solve(int x);
//dp[i][0]:i位无不吉利
//dp[i][1]:i位无不吉利,最高位为2
//dp[i][2]:i位有不吉利
int main()
{
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for(int i=1;i<=8;i++)
    {
        dp[i][0]=dp[i-1][0]*9-dp[i-1][1];//在首位加除4外的9个数,减去i-1位最高位为2且在首位加6
        dp[i][1]=dp[i-1][0];
        dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1];
    }
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0)
            break;
        printf("%d\n",solve(m+1)-solve(n));
    }
    return 0;
}
int solve(int x)//求得0-(x-1)满足条件的数的个数
{
    int xx=x-1;
    int digit[10];
    int cnt;
    for(cnt=1;;cnt++)
    {
        digit[cnt]=x%10;
        x/=10;
        if(x==0)
            break;
    }
    digit[cnt+1]=0;
    int ans=0;
    bool flag=false;
    for(int i=cnt;i>0;i--)//从高位到低位依次比较
    {
        ans+=digit[i]*dp[i-1][2];
        if(flag)
            ans+=digit[i]*dp[i-1][0];
        else
        {
            if(digit[i]>6)
                ans+=dp[i-1][1];
            if(digit[i]>4)
                ans+=dp[i-1][0];
            if(digit[i+1]==6&&digit[i]>2)
                ans+=dp[i][1];
        }
        if(digit[i]==4||(digit[i+1]==6&&digit[i]==2))
            flag=true;
    }
    return xx-ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: