HDU3555 区间的数里面有49的个数(数位dp)

Posted shuaihui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU3555 区间的数里面有49的个数(数位dp)相关的知识,希望对你有一定的参考价值。

题目:区间的数里面有49的个数

分析:

dp[pos][0]:长度为pos的数中,不包含49的,前一位不为4的有多少个;
dp[pos][1]:长度为pos的数中,不包含49的,前一位为4的有多少个;
dp[pos][2]:长度为pos的数中,包含49的有多少个;

 

一开始我是打算先算不满足的,在算满足的;结果不行,可能这样算出来的数太大了所以不行吧;

通过这道题可以更加理解了(不要62)这个题目的sta 的表示 , 原来如此呀

技术分享图片
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long ll;
int dig[20];
ll dp[20][3];
/*
dp[pos][0]:长度为pos的数中,不包含49的,前一位不为4的有多少个;
dp[pos][1]:长度为pos的数中,不包含49的,前一位为4的有多少个;
dp[pos][2]:长度为pos的数中,包含49的有多少个;
*/
ll dfs(int pos,int pre,bool have49,bool limit)
{
    if(pos==0) return have49;
    if(!limit)//首先满足没有上界限制
    {
        if(have49 && ~dp[pos][2]) return dp[pos][2];
        if(!have49 && pre==4 && ~dp[pos][1]) return dp[pos][1];
        if(!have49 && pre!=4 && ~dp[pos][0]) return dp[pos][0];
    }

    int up=limit?dig[pos]:9;
    ll ans=0;
    for(int i=0;i<=up;i++)
    {
        if(pre==4 && i==9) ans+=dfs(pos-1,i,1,limit && i==up);
        else ans+=dfs(pos-1,i,have49,limit && i==up);
    }

    if(!limit)
    {
        if(have49) dp[pos][2]=ans;
        else
        {
            if(pre==4) dp[pos][1]=ans;
            else dp[pos][0]=ans;
        }
    }

    return ans;
}
ll solve(ll x)
{
    int pos=0;
    while(x)
    {
        dig[++pos]=x%10;
        x/=10;
    }
    return dfs(pos,0,0,1);
}

int main()
{
    int T;
    ll N;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d",&N);
        memset(dp,-1,sizeof(dp));
        printf("%I64d
",solve(N));
    }
}
View Code

 



以上是关于HDU3555 区间的数里面有49的个数(数位dp)的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3555 Bomb (数位DP)

HDU 3555 数位dp入门

HDU 3555——Bomb

Bomb HDU 3555 dp状态转移

数位DP题集

hdu3555 数位dp