zoukankan      html  css  js  c++  java
  • hdu 4722 (数位DP)

    Good Numbers

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3360    Accepted Submission(s): 1064

    Problem Description
    If we sum up every digit of a number and the result can be exactly divided by 10, we say this number is a good number. You are required to count the number of good numbers in the range from A to B, inclusive.
     
    Input
    The first line has a number T (T <= 10000) , indicating the number of test cases. Each test case comes with a single line with two numbers A and B (0 <= A <= B <= 1018).
     
    Output
    For test case X, output "Case #X: " first, then output the number of good numbers in a single line.
     
    Sample Input
    2
    1 10
    1 20
     
    Sample Output
    Case #1:
    0
    Case #2:
    1
    Hint
    The answer maybe very large, we recommend you to use long long instead of int.
     
    Source
     
    Recommend
    zhuyuanchen520   |   We have carefully selected several similar problems for you:  5235 5234 5233 5232 5231 
    题目描述:假设一个数每位数上之和能被10整除,称这个数为好数,给定两个数,求在这个范围内的好数.
    可以找规律,也可以采用递推。
    设d[i][j]表示以i长度的对10取余为j的数的数量。
    d[i+1][(j+k)%10]+=d[i][j];
    通过d[i][j]进行递推,j代表的是余数,从0到9进行枚举,
    由于每一位上都有数的限制,我们可以选择先把这一位上的0到9全部枚举,然后减去超过这个数的,或者先把之前一位的数先枚举到比它那个数小的范围,这一位从0到9枚举
    ,然后加上。
    答案应该是d[r][0]-d[l-1][0],之前写错了。
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include<vector>
    #include<algorithm>
    #define  LL  long long
    #define maxn 10
    #define MAXN 100000
    #define inf 0x3f3f3f3f3f3f3f
    using namespace std;
    LL dp[20][20];
    int c[20],d[20];
    LL x,y;
    LL xx,yy;
    void init()
    {
      memset(dp,0,sizeof(dp));
    }
    int getnum(LL num,int  s[])
    {
        int t=1;
        while(num>0)
        {
            s[t++]=num%10;
            num/=10;
        }
        for(int i=1;i<=(t-1)/2;i++)
            swap(s[i],s[t-i]);
        return t-1;
    }
    LL solve(LL len,int *s)
    {
    
       // printf("%d
    ",s[1]);
        //printf("%d
    ",s[2]);
         for(int i=0;i<=s[1];i++)
            dp[1][i]=1;
            int x=s[1];
        for(int i=1;i<=len-1;i++)
        {
            for(int j=0;j<=9;j++)
          {
              for(int k=0;k<=9;k++)
            {
              /*if(i==1 && j==0)
              continue;*/
              dp[i+1][(j+k)%10]+=dp[i][j];
            }
          }
          for(int pp=s[i+1]+1;pp<=9;pp++)
          {
              int t=(x+pp)%10;
              dp[i+1][t]--;
          }
          x=(x+s[i+1])%10;
        }
    
        /* for(int i=1;i<=len;i++)
         {
             for(int j=0;j<=9 ;j++)
             {
                 printf("%lld ",dp[i][j]);
             }
             printf("
    ");
         }*/
         //for(int i=2;i<=len;i++)
           // dp[i][0]+=dp[i-1][0];
       //  for(int i=1;i<=len;i++)
           // printf("%lld	",dp[i][0]);*/
            return dp[len][0];
    
    }
    int main()
    {
       int T;
       scanf("%d",&T);
       for(int i=1;i<=T;i++)
       {
           init();
           scanf("%I64d%I64d",&x,&y);
           xx=getnum(x-1,c);
           yy=getnum(y,d);
           LL answer1,answer2;
           answer1=solve(xx,c);
           memset(dp,0,sizeof(dp));
           answer2=solve(yy,d);
          /* for(int i=1;i<=xx;i++)
            printf("%d",c[i]);
             printf("
    ");
           for(int i=1;i<=yy;i++)
            printf("%d",d[i]);
           printf("
    ");*/
         //  printf("%lld
    ",answer2);
          // printf("%lld
    ",answer1);
           printf("Case #%d: %I64d
    ",i,answer2-answer1);
       }
        return 0;
    }
     
  • 相关阅读:
    浏览器拦截跨域请求处理方法
    如何保护java程序不被反编译
    python面对对象面试题
    面向对象之继承
    面向对象之多态
    面向对象之组合
    面向对象初始
    python之匿名函数
    python之内置函数
    azure连接redis
  • 原文地址:https://www.cnblogs.com/xianbin7/p/4530837.html
Copyright © 2011-2022 走看看