HDU ~ 3555 ~ Bomb (数位DP)

题意

问1~n区间内有多少个含有'49'的数?

 

题解

本题同:HDU ~ 2089 ~ 不要62 (数位DP),我们求出来0~n中不含49的个数cnt,n+1-cnt就是含有49的个数。

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 20;
const int INF = 0x3f3f3f3f;
typedef long long LL;
LL n, dp[20];
string s;
LL dfs(int pos, int pre, bool limit)
{
    if (pos == -1) return 1;
    if (!limit && pre != 4 && dp[pos] != -1) return dp[pos];
    LL ans = 0;
    int E = limit?s[pos]-'0':9;
    for (int i = 0; i <= E; i++)
    {
        if (pre == 4 && i == 9) continue;
        ans += dfs(pos-1, i, limit&&i==E);
    }
    if (!limit && pre != 4) dp[pos] = ans;
    return ans;
}
LL solve(LL x)
{
    s = to_string(x); reverse(s.begin(), s.end());
    return dfs(s.size()-1, -1, 1);
}
int main()
{
    memset(dp, -1, sizeof(dp));
    int T; scanf("%d", &T);
    while (T--)
    {
        scanf("%lld", &n);
        printf("%lld\n", n+1-solve(n));
    }
    return 0;
}
/*
3
1
50
500
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值