zoukankan      html  css  js  c++  java
  • 不要62(hdu 2089 数位DP)

    不要62

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


    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
     
    Author
    qianneng
     
    Source
     
    疑问:  如果要统计有49的数量  我们也是反过来 总共的数量减去不是49的数量   if(len==0)  return 1; //当长度为0时必然返回1
     
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n,m;
     5 int dp[20][20];   //前i位首位时j的符合条件的数量
     6 int digit[20];
     7 
     8 void init(){
     9     dp[0][0]=1;
    10     for(int i=1;i<=7;i++){
    11         for(int j=0;j<=9;j++){  //
    12             for(int k=0;k<=9;k++){
    13                 if(j!=4&&(j!=6||k!=2)){
    14                     dp[i][j]+=dp[i-1][k];  //符合条件的数量
    15                 }
    16             }
    17         }
    18     }
    19 }
    20 
    21 int solve(int ee){
    22     int len=0,ans=0;
    23     while(ee){
    24         digit[++len]=ee%10;
    25         ee/=10;
    26     }
    27     digit[len+1]=0;
    28 
    29     for(int i=len;i>=1;i--){   //从高位开始
    30         for(int j=0;j<digit[i];j++){
    31             if((digit[i+1]==6&&j==2)||(j==4)) continue;
    32             ans+=dp[i][j];
    33         }
    34         if(digit[i]==4||(digit[i+1]==6&&digit[i]==2)) break;    //如果当前这一位不符合直接退出
    35     }
    36     return ans;
    37 }
    38 
    39 
    40 
    41 int main(){
    42     ios::sync_with_stdio(false);
    43     init();
    44     while(cin>>n>>m&&(n+m)){
    45         cout << solve(m+1)-solve(n) << endl;
    46     }
    47     return 0;
    48 
    49 }
    不是dfs版的
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 int n,m;
     5 int digit[20];
     6 int dp[20][2];
     7 
     8 int dfs(int len,bool if6,bool limit){  ///limit为上界
     9     if(len==0) return 1;
    10     if(!limit&&dp[len][if6]) return dp[len][if6];   //不是上界且访问过 记忆化搜索
    11     int cnt=0,up_bound=(limit?digit[len]:9);  //如果上一个是上届 这个也得确定上届
    12     for(int i=0;i<=up_bound;i++){
    13         if(if6&&i==2) continue;  //统计不是62  
    14         if(i==4) continue;   //统计不是4
    15         cnt+=dfs(len-1,i==6,limit&&i==up_bound);
    16     }
    17     if(!limit) dp[len][if6]=cnt;   //上一位不是上届  如果上一位是上届得重新计算
    18     return cnt;
    19 }
    20 
    21 int solve(int ee){
    22     int jishu=0;
    23     while(ee){
    24         digit[++jishu]=ee%10;
    25         ee/=10;
    26     }
    27     return dfs(jishu,false,true);
    28 }
    29 
    30 int main(){
    31     ios::sync_with_stdio(false);
    32 
    33     while(cin>>n>>m,n+m){
    34         cout << solve(m)-solve(n-1) << endl;
    35     }
    36 
    37     return 0;
    38 }
    dfs版本的
  • 相关阅读:
    linux常用命令
    linux下redis配置
    Git使用命令
    linux学习笔记
    NOPI读取Excel2003、Excel2007或更高级的兼容性问题
    netcore开发常用命令
    netcore3.0 dotnet ef执行报错
    vscode配置nuget常见问题
    PDMReader结合PowerDesigner导出word格式数据字典
    微信网页授权开发遇到问题
  • 原文地址:https://www.cnblogs.com/qq-1585047819/p/11951719.html
Copyright © 2011-2022 走看看