zoukankan      html  css  js  c++  java
  • hdu2089-不要62-(数位dp)

    不要62

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 64682    Accepted Submission(s): 25712


    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入门:
    dp[i][j]表示从右往左数第i位上以j开头的 符合要求的数有多少个
    dp[i][j]是对dp[i-1][k]的累加,满进
    举例说明:

    3253
    dp[4][0] 0000-0999
    dp[4][1] 1000-1999
    dp[4][2] 2000-2999 3000

    dp[3][0] 0000-0099
    dp[3][1] 0100-0199 200

    dp[2][0] 0000-0009
    dp[2][1] 0010-0019
    dp[2][2] 0020-0029
    dp[2][3] 0030-0039
    dp[2][4] 0040-0049 50

    dp[1][0] 0
    dp[1][1] 1
    dp[1][2] 2 3 一共表示0-3252这3253个数中符合要求的数有多少个

    2403
    dp[4][0] 0000-0999
    dp[4][1] 1000-1999

    dp[3][0] 0000-0099
    dp[3][1] 0100-0199
    dp[3][2] 0200-0299
    dp[3][3] 0300-0399
    break; 遇到本位是4则后面的位数都不用算了

    2623
    dp[4][0] 0000-0999
    dp[4][1] 1000-1999 2000

    dp[3][0] 0000-0099
    dp[3][1] 0100-0199
    dp[3][2] 0200-0299
    dp[3][3] 0300-0399
    dp[3][4] 0400-0499
    dp[3][5] 0500-0599 600

    dp[2][0] 0000-0009
    dp[2][1] 0010-0019 20
    break; 遇到本位是2,上一位是6的后面的位数也不用算了

    2003
    dp[4][0] 0000-0999
    dp[4][1] 1000-1999 2000

    dp[1][0] 0
    dp[1][1] 1
    dp[1][2] 2 3 遇到本位是0的直接跳过,没有满进到1就用不了dp[3][0]和dp[2][0]

    #include<cstring>
    #include<algorithm>
    #include<stdio.h>
    #include<iostream>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int dp[10][10];
    int a[10];
    
    void init()
    {
        memset(dp,0,sizeof(dp));
        dp[0][0]=1;
        for(int i=1;i<10;i++)
        {
            for(int j=0;j<10;j++)
            {
                if(j==4) continue;
                for(int k=0;k<10;k++)
                {
                    if(j==6 && k==2) continue;
                    dp[i][j]+=dp[i-1][k];
                }
            }
        }/*打印dp表看看啥情况
        for(int i=0;i<10;i++)
        {
            for(int j=0;j<10;j++)
            {
                printf("%10d",dp[i][j]);
            }
            printf("
    ");
        }*/
    }
    
    int slove(int x)
    {
        int cnt=0;
        int temp=x;
        while(x)
        {
            x=x/10;
            cnt++;
        }
        x=temp;
        memset(a,0,sizeof(a));///a数组从下标1到cnt顺序存储各个位上的数字,人性化
        for(int i=cnt;i>=1;i--)
        {
            a[i]=x%10;
            x=x/10;
        }
        int sum=0;for(int i=1;i<=cnt;i++)///数组下标从小到大 
        {
            int c=a[i];
            
            for(int j=0;j<c;j++)
            {    
                if(a[i-1]==6 && j==2) continue;
                sum+=dp[ cnt+1-i ][j];
            }
            if(c==4 || (c==2 && a[i-1]==6) )
                break;
        }
        return sum;
    }
    
    
    int main()
    {
        init();
        int n,m;
        while( scanf("%d %d",&n,&m) && (n+m) )
        {
            int ans=slove(m+1)-slove(n);
            printf("%d
    ",ans);
        }
        return 0;
    }
     
  • 相关阅读:
    模拟登陆江西理工大学教务系统
    python3爬虫 -----华东交大校园新闻爬取与数据分析
    以selenium模拟登陆12306
    PAT (Basic Level) Practice (中文)1076 Wifi密码 (15 分)
    PAT (Basic Level) Practice (中文)1047 编程团体赛 (20 分)
    PAT (Basic Level) Practice (中文)1029 旧键盘 (20 分)
    PAT (Basic Level) Practice (中文)1016 部分A+B (15 分)
    PAT (Basic Level) Practice (中文)1031 查验身份证 (15 分)
    PAT (Basic Level) Practice (中文)1041 考试座位号 (15 分)
    PAT (Basic Level) Practice (中文)1037 在霍格沃茨找零钱 (20 分)
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10567931.html
Copyright © 2011-2022 走看看