码迷,mamicode.com
首页 > 其他好文 > 详细

2019年9月训练(壹)数位DP (HDU 2089)

时间:2019-09-16 19:18:43      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:style   除了   +=   差分   情况   tps   problem   can   ==   

开学之后完全没时间写博客....

HDU 2089 不要62(vjudge) 数位DP

思路:

题目给出区间[n,m] ,找出不含4或62的数的个数

用一个简单的差分:先求0~m+1的个数,再减去0~n的个数.

但问题依旧不简单,再次简化为求0~i位数中不含4或62的数的个数.

i=1 //0~9中
i=2 //0~99中
i=3 //0~999中
......
dp[i][0] //0~i位数中的吉利数
dp[i][1] //0~i位数中以2打头的吉利数
dp[i][2] //0~i位数中的非吉利数(含4或62)

所以第i位数中的吉利数个数为:

dp[i][0]=dp[i-1][0]*9-dp[i-1][i]

第i位数中以2打头的幸运数个数为:

dp[i][1]=dp[i-1][0]

第i位数中的非吉利数个数为:

dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1]

同时初始值为:

dp[0][0]=1;
dp[0][1]=0;
dp[0][2]=0;

AC码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int dp[10][5];

void INIT()
{
    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个数,减去在2前补6的个数 
        dp[i][1]=dp[i-1][0];//吉利数在首位补2 
        dp[i][2]=dp[i-1][2]*10+dp[i-1][0]+dp[i-1][1];//不吉利的情况 
    }
}

int work(int x)
{
    int d[20],cnt=0,temp=x;
    while(temp)
    {
        d[++cnt]=temp%10;
        temp/=10;
    }
    d[cnt+1]=0;
    int flag=0,ans=0;
    for(int i=cnt;i>0;i--)
    {
        ans+=d[i]*dp[i-1][2];//用前一位所以不吉利数推出 
        if(flag) ans+=d[i]*dp[i-1][0];// 之前有不吉利数 
        else
        {
            if(d[i]>4) ans+=dp[i-1][0];//4 
            if(d[i]>6) ans+=dp[i-1][1];//6 
            if(d[i+1]==6&&d[i]>2) ans+=dp[i][1];//62 
        }
        if(d[i]==4||(d[i+1]==6&&d[i]==2)) flag=1;
    }
    return x-ans;//减去不吉利数的个数 
}

int main()
{
    int m,n;
    INIT();
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0) break;
        printf("%d\n",work(m+1)-work(n));
    }
    return 0;
} 

2019-09-16 18:50:26

2019年9月训练(壹)数位DP (HDU 2089)

标签:style   除了   +=   差分   情况   tps   problem   can   ==   

原文地址:https://www.cnblogs.com/plzplz/p/11528975.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!