zoukankan      html  css  js  c++  java
  • HDU 3555 Bomb (数位dp)

    题意:求【1,n】当中包含49的一共有多少个数字?

    思路:用dp[i][0]来表示 数字位数小于等于i并且不包含49的数字个数,之所以说小于等于而不是严格等于因为有可能有前导零。

    dp[i][1]表示 数字位数等于i 并且开头为9,不含“49” 的个数。

    dp[i][2] 表示数字位数小于等于i并且包含“49”的个数

    初始化完成之后,那么计算给定的n,统计的时候就是对于n的每一位(从高到低)

    假设当前是第i位(最右边为第1位),那么这一位的贡献肯定有 dp[i - 1][2] * digit[i];再者,如果这一位大于4的话,那么一定可以贡献出来一个4对应后面的9开头的 从而组成符合条件的数,所以再加上dp[i - 1][1], 如果前面有49了,那么后面的一定是加起来所有的就是(dp[i - 1][2] + dp[i - 1][0]) * digit[i],因为刚开始加过dp[i - 1][2],所以这里直接加dp[i -1][0]就行了。

    /*************************************************************************
        > File Name:            bomb.cpp
        > Author:               Howe_Young
        > Mail:                 1013410795@qq.com
        > Created Time:         2015年09月15日 星期二 18时38分25秒
     ************************************************************************/
    
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    typedef long long ll;
    const int maxn = 23;
    ll dp[maxn][3];
    //dp[i][0] representation the length less than or equal i not include 49 (may be start with 9, but not include 49)
    //dp[i][1] representation the length equal i and not include 49 but start with 9
    //dp[i][2] representation the length less than or equal i include 49
    void init()
    {
        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];
        }
    }
    
    ll get_cnt(ll n)
    {
        int digit[maxn], tot = 0;
        while (n)
        {
            digit[++tot] = n % 10;
            n /= 10;
        }
        digit[tot + 1] = 0;
        ll ans = 0;
        bool flag = false;
        for (int i = tot; i >= 1; i--)
        {
            ans += digit[i] * dp[i - 1][2];
            if (flag)
                ans += digit[i] * dp[i - 1][0];
            else 
            {
                if (digit[i] > 4) ans += dp[i - 1][1];
                if (digit[i + 1] == 4 && digit[i] == 9) flag = true;
            }
        }
        if (flag) ans++;
        return ans;
    }
    int main()
    {
        init();
        int T; ll n;
        scanf("%d", &T);
        while (T--)
        {
            cin >> n;
            cout << get_cnt(n) << endl;
        }
        return 0;
    }
  • 相关阅读:
    spark 读取mongodb失败,报executor time out 和GC overhead limit exceeded 异常
    在zepplin 使用spark sql 查询mongodb的数据
    Unable to query from Mongodb from Zeppelin using spark
    spark 与zepplin 版本兼容
    kafka 新旧消费者的区别
    kafka 新生产者发送消息流程
    spark ui acl 不生效的问题分析
    python中if __name__ == '__main__': 的解析
    深入C++的new
    NSSplitView
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4811426.html
Copyright © 2011-2022 走看看