HDU3555 Bomb【Digital DP】

Title link: HDU3555 Bomb

Question meaning: ask the number of 49 in 1~n;

Analysis: First use init() to find out how many of the n-digit numbers contain 49;

dp[i[[j] is used to store the number of qualified numbers i represents the length of the currently processed number is i; here the number processed by dp[i][j] can contain leading zeros;

dp[i][0] represents the number that does not contain 49 in the number of length i;

dp[i][1] represents the number of numbers with a length of i that do not contain 49 but the highest digit is 9;

dp[i][2] represents the number of numbers containing 49 in the number of length i;

Then start to find how many numbers less than the given number contain 49;

Scan backwards, when the len position is reached, the len position is the largest number that can be placed before the given number (that is, a[i]), and the len position is less than the given number (that is, a[i]);

#include<iostream>
#include<cstring>
#include<string.h>
#include<cmath>
#include<algorithm>
#define ll long long int
#define ull unsigned long long int
using namespace std;
int a[25];
ll dp[21][3];
int t;
ull n;
int main()
{
    scanf("%d",&t);
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for (int i=1;i<21;i++)
    {
        dp[i][0]=dp[i-1][0]*10-dp[i-1][1];
        dp[i][1]=dp[i-1][0];
        dp[i][2]=dp[i-1][2]*10+dp[i-1][1];
    }
    while (t--)
    {
        scanf("%llu",&n);
        int len=0;
        memset(a,0,sizeof(a));
        n++;
        while (n)
        {
            a[++len]=n%10;
            n/=10;
        }
        ll ans=0;
        int last=0;
        bool flag=false;
        for (int i=len;i>0;i--)
        {
            ans+=(dp[i-1][2]*a[i]);
            if (flag) ans+=dp[i-1][0]*a[i];
            if (!flag && a[i]>4) ans+=dp[i-1][1];
            if (last==4 && a[i]==9) flag=true;
            last=a[i];
        }
        printf("%lld\n",ans);
    }
    return 0;
} 

 

Guess you like

Origin blog.csdn.net/qq_43813163/article/details/102556552