zoukankan      html  css  js  c++  java
  • 数位dp

    //hdu  2089

    不要62

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


    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
     
     
     
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <queue>
     7 #include <set>
     8 #include <map>
     9 #include <string>
    10 #include <cmath>
    11 #include <cstdlib>
    12 #include <ctime>
    13 using namespace std;
    14 typedef long long ll;
    15 const ll mod = 1e9+7;
    16 int  n,m,d[20],dp[20][2];
    17 //dp[pos][state]:state 前一位是6吗
    18 int dfs(int pos,bool  state,bool limit)
    19 {
    20     if(pos==0) return 1;
    21     //如果有limit 肯定是不行的
    22     if(!limit&&dp[pos][state]!=-1) return dp[pos][state];//避免重复
    23      //为什么要返回呢?可以画图理解当我们搜到3XXX时,程序运行到
    24      //1XXX时就已经把3XXX之后的搜索完了,记忆化也是这个用意.
    25     int sum=0,up=limit?d[pos]:9;//up :上限
    26     for(int  i=0;i<=up;i++){
    27         if(i==4||(state&&i==2)) continue;//state:i==6
    28         else{
    29             sum+=dfs(pos-1,i==6,limit&&i==d[pos]);//只有之前有限制现在又达到了上限
    30         }
    31     }
    32     if(!limit) dp[pos][state] = sum;
    33     return  sum;
    34 }
    35 int  solve(int  x){
    36     int pos=0;
    37     while(x){
    38         d[++pos]=x%10;
    39         x/=10;
    40     }
    41     return dfs(pos,false,true);//最高位:state一定false(!=6) limit 一定有
    42 }
    43 int  main()
    44 {
    45     while(~scanf("%d%d",&n,&m)){
    46         if(n==0&&m==0) break;
    47         memset(dp,-1,sizeof(dp));//易忘
    48         printf("%d
    ",solve(m)-solve(n-1));
    49     }
    50     return 0;
    51 }

    华东交通大学2018年ACM“双基”程序设计竞赛

    G 7的意志
    定义一个序列a:7,77,777......,7777777(数字全为7的正整数,且长度可以无限大)
    clearlove7需要从含有7的意志的数里获得力量,如果一个整数能被序列a中的任意一个数字整除,并且其数位之和为序列a中任意一个数字的倍数,那么这个数字就含有7的意志,现在给你一个范围[n,m],问这个范围里有多少个数字含有7的意志。
     

    输入描述:

    多组输入,每行两个个整数n,m(1<=n<=m<=1e18),如果输入为"0 0",停止程序。

    输出描述:

    每一行输出含有7的意志的数的个数。
    示例1

    输入

    复制
    1 7
    1 100
    1 1000
    0 0
    

    输出

    复制
    1
    3
    21

    说明

    1到100中符合条件的数字为7,70,77



     1 j//就是%7 
     2 #include <cstdio>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 #include <cstring>
     7 using namespace std;
     8 #define ll long long
     9 const int mod=1e9+7;
    10 //ll dp[21][9][9]:20+1,8+1 不然会数组越界
    11 ll dp[21][9][9];//dp[pos][sum1][sum2]:pos:第几位,
    12 //  sum1 :从第一位到第pos位的数%7的值
    13 // sum2 :从第一位到第pos位的数的和%7的值
    14 // 123 sum1 : 1 (1*10+2)%7==5 (5*10+3)%7==4
    15 //123 sum2 : 1 3 6 
    16 ll  d[20];
    17 void  init()
    18 {
    19     for(int  i=0;i<=20;i++){
    20         for(int j=0;j<=8;j++){
    21             for(int k=0;k<=8;k++){
    22                 dp[i][j][k]  = -1;
    23             }
    24         }
    25     }
    26 }
    27 ll dfs(int pos,int  sum1,int  sum2,bool limit){
    28     if(pos==0) return (sum1%7==0&&sum2%7==0);
    29     if(!limit&&dp[pos][sum1][sum2]!=-1) return  dp[pos][sum1][sum2];
    30     int up=limit?d[pos]:9;
    31     ll ret = 0;
    32     for(int i=0;i<=up;i++){
    33         ret+=dfs(pos-1,(sum1*10+i)%7,(sum2+i)%7,limit&&i==d[pos]);
    34     }
    35     if(!limit) {
    36         dp[pos][sum1][sum2] = ret;
    37     }
    38     return  ret;
    39 }
    40 ll solve(ll x){    
    41     int pos= 0;
    42     while(x)
    43     {
    44         d[++pos] =x%10;
    45         x/=10;        
    46     }    
    47     return dfs(pos,0,0,true);//pos==0才算一个,因此pos时sum1,sum2都为0
    48 }
    49 ll n,m;
    50 int  main()
    51 {
    52     init();//类似于预处理
    53     while(~scanf("%lld%lld",&n,&m)){
    54         if(n==0&&m==0) break;
    55         solve(m);
    56         printf("%lld
    ",solve(m)-solve(n-1));
    57     }
    58     return  0;
    59 }
  • 相关阅读:
    经历:如何设置jquery easyui中下拉框不可编辑
    经历:easyui的layout自适应高度布局
    JavaScript高级程序设计(九):基本概念----函数
    JavaScript高级程序设计(九):基本概念----语句的特殊点
    JavaScript高级程序设计(八):基本概念--操作符
    JavaScript高级程序设计(三):基本概念:数据类型
    JavaScript高级程序设计(七):JavaScript中的in关键字
    JavaScript高级程序设计(六):关键字 void 和 delete 使用
    JavaScript高级程序设计(五): js的关键字instanceof和typeof使用
    SQL Server 存储过程
  • 原文地址:https://www.cnblogs.com/tingtin/p/9977323.html
Copyright © 2011-2022 走看看