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;
    }
  • 相关阅读:
    实现只有0,1,2三种元素的乱序数组的排序
    请说明Request和Session的生命周期
    使用Enumeration和Iterator遍历集合类
    hive中分组取前N个值的实现
    世界知名网站的技术实现(转)
    蚂蚁变大象:浅谈常规网站是如何从小变大的(转)
    Hadoop管理员的十个最佳实践(转)
    internet笔记
    Instagram 架构分析笔记(转)
    Apache Pig入门 –介绍/基本架构/与Hive对比(转)
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4811426.html
Copyright © 2011-2022 走看看