• 【数位DP】Hdu 2089:不要62


              不要62

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


    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最基础的题目。。
      
      首先我们设数组f[i][j]代表第i位是j有f[i][j]种情况。
      
      然后我们用预处理出10位以下的f[i][j].
      
      转移大约是f[i][j]=f[i-1][k](k!=4&&j!=4&&!(j==6&&k==2))
      
      然后求出这个以后,我们可以认为答案=1-R之间的数字个数-1-L之间的数字个数
      
      大约是对于一个数字,先把它存入一个数组
      
      然后对于最高位,可以是0-num[len].
      
      这里分三种情况:
        1.是0的情况,这是我们推向更低位。
        2.是num[len],我们也推向更低位。
        3.其他情况直接加f数组。
      
      对于1情况,我们直接把len-1到1的位数的每一位设为1-9然后加上f[i][j].这样处理完了所有位的所有情况。
      
      对于2情况,就是下一位的3种情况和。
      
      3情况不用说。  
      注意考虑合法情况。
      
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 
     6 using namespace std;
     7 
     8 int f[11][11];
     9 
    10 void DP()
    11 {
    12     for(int i=0;i<=9;i++)
    13     if(i!=4)f[1][i]=1;
    14     for(int i=2;i<=9;i++)
    15     for(int j=0;j<=9;j++)
    16         if(j!=4)
    17         for(int kk=0;kk<=9;kk++)
    18             if(kk!=4&&!(j==6&&kk==2))
    19             f[i][j]+=f[i-1][kk];
    20 }
    21 
    22 int get(int x)
    23 {
    24     int num[11],len=0,res=0;
    25     while(x)
    26     {
    27     num[++len]=x%10;
    28     x/=10;
    29     }
    30     for(int i=1;i<num[len];i++)
    31     res+=f[len][i];
    32     for(int i=1;i<=len-1;i++)
    33     for(int j=1;j<=9;j++)
    34         res+=f[i][j];
    35     if(num[len]==4)return res;
    36     for(int i=len-1;i>=1;i--)
    37     {
    38     for(int j=0;j<num[i];j++)
    39     {
    40         if(j==4 || (j==2 && num[i+1]==6) )continue;
    41         res+=f[i][j];
    42     }
    43     if(num[i]==4 || (num[i+1]==6 && num[i]==2) )break;
    44     }
    45     return res;
    46 }
    47 
    48 int main()
    49 {
    50     DP();
    51     int l,r,num,snum,ans=0;
    52     while(1)
    53     {
    54     scanf("%d%d",&l,&r);
    55     if(!(l&&r))break;
    56     printf("%d
    ",get(r+1)-get(l));
    57     }
    58     return 0;
    59 }
    View Code
      
  • 相关阅读:
    《PHP面试笔试真题库》——PHP面试的好帮手
    PHP面试常考之会话控制
    PHP面试常考内容之Memcache和Redis(2)
    PHP面试常考内容之Memcache和Redis(1)
    PHP面试常考内容之面向对象(3)
    SQL全表扫描优化基础知识
    Windows CMD命令大全
    Asp.net 获取客户端的信息
    sql日期创建
    sql语句去掉前面的0(前导零,零前缀)
  • 原文地址:https://www.cnblogs.com/tuigou/p/4832678.html
Copyright © 2020-2023  润新知