• 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
  • 相关阅读:
    命令行工具
    案例 WordCount
    Spark 运行环境
    启动 Local 环境
    Spark 快速上手
    spark异常处理
    第六章:(4)死锁
    第五章:(3)HashMap 集合线程不安全&解决方案
    第五章:(2)HashSet 集合线程不安全&解决方案
    第八章:(1)CountDownLatch减少计数
  • 原文地址:https://www.cnblogs.com/00isok/p/9384342.html
Copyright © 2020-2023  润新知