zoukankan      html  css  js  c++  java
  • HDU 2089 不要62 【数位dp】

    <题目链接>

                                                 不要62

    Problem Description
    杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
    杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
    不吉利的数字为所有含有4或62的号码。例如:
    62315 73418 88914
    都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
    你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。
     
    Input
    输入的都是整数对n、m(0<n≤m<1000000),如果遇到都是0的整数对,则输入结束。
     
    Output
    对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。
     
    Sample Input
    1 100
    0 0
     
    Sample Output
    80
     
     
    解题分析:
    此题是一道数位dp的入门题,当然,此题你也可以用打表+前缀和解决。下面是这道题的详细解答     >>>
     
    # include<cstdio>
    # include<iostream>
    # include<cstring>
    
    using namespace std;
    
    int dp[10][10];//dp[i][j]表示的是以j开头的i位数中,不含4和62的个数
    int digit[10];
    
    void init()                         //先打一张表,预先算出题目可能需要的所有dp[i][j];
    {
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;                  
        for (int i = 1; i <= 7; i++)
        {
            for (int j = 0; j <= 9; j++)
            {//枚举第i位
                for (int k = 0; k <= 9; k++)
                {//枚举第i-1位
                    if (j != 4 && (!(j == 6 && k == 2)))
                    {
                        dp[i][j] = dp[i][j] + dp[i - 1][k];
                    }
                }
            }
        }
    }
    
    
    int sum(int n)              //求的是小于n的数字有多少个,从下面的j<digit[i]可以看出
    {
        int len = 0;
        int ans = 0;
        while (n != 0)
        {
            digit[++len] = n % 10;
            n = n / 10;
        }
        digit[len + 1] = 0;
    
        for (int i = len; i >= 1; i--)             //i表示枚举的数字的位数,j表示,所有小于n的各位数为起点的数的数量
        {
    
            for (int j = 0; j < digit[i]; j++)
            {
                if (j != 4 && (!(digit[i + 1] == 6 && j == 2)))         //注意这里是i+1,因为digit内是按位数从小到大的顺序存的
                {
                    ans += dp[i][j];              
                }
            }
            if (digit[i] == 4 || (digit[i] == 2 && digit[i + 1] == 6))
            {
                break;
            }
    
        }
    
        return ans;
    }
    
    int main(void)
    {
        int n, m;
        while (cin >> n >> m, n || m)
        {
            init();
    
            printf("%d
    ", sum(m+1) - sum(n));
        }
        return 0;
    }
     
     
     
    2018-07-29
  • 相关阅读:
    ThinkPHP 3.2.2 实现持久登录 ( 记住我 )
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 20 有效的括号
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 19删除链表的倒数第N个节点
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 18 四数之和
    Java实现 LeetCode 17 电话号码的字母组合
  • 原文地址:https://www.cnblogs.com/00isok/p/9384342.html
Copyright © 2011-2022 走看看