zoukankan      html  css  js  c++  java
  • hdu 4722 Good Numbers( 数位dp入门)

    Good Numbers

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


    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

    题意:给定区间A到B(用 long long),求其间好数有多少,好数是指每位数字加起来的和对10取余结果是0。

    当时不明白何为学长讲的边界,另外数位dp还有递推版,但是递推太容易出错,还是记忆化搜索比较容易理解~

     1 #include<iostream>
     2 #include<vector>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <math.h>
     7 #include<algorithm>
     8 #define ll long long
     9 #define eps 1e-8
    10 using namespace std;
    11 ll dp[20][20]; // 统计第几位数余数为几有多少个
    12 int num[20]; //存放每位数字
    13 ll dfs(int site,int mod,int f)
    14 {
    15     if(site == 0)
    16         return mod == 0 ? 1:0; // 递归结束条件,并判断最后一位时是否余数为0
    17     if(!f && dp[site][mod] != -1) //记忆化搜索
    18         return dp[site][mod];
    19     int len = f == 1?num[site]:9; //若当前位为边界則当前位只枚举0-当前,否则枚举0-9
    20     ll ans = 0;
    21     for(int i = 0; i <= len; i++)
    22         ans += dfs(site-1,(mod+i)%10,f && i == len);//f判断是否为边界
    23     if(!f)
    24         dp[site][mod] = ans; //边界不能存,因为之前计算的是不看边界的,便于以后用到,如果存了,就是一个错误的统计
    25     return ans;
    26 }
    27 ll solve(ll digit)
    28 {
    29     memset(num,0,sizeof(num));
    30     int l = 0;
    31     while(digit)
    32     {
    33         num[++l] = digit%10;
    34         digit /= 10;
    35     }
    36     return dfs(l,0,1);
    37 }
    38 int main(void)
    39 {
    40     int t,cnt = 1;
    41     ll a,b;
    42     memset(dp,-1,sizeof(dp));
    43     scanf("%d",&t);
    44     while(t--)
    45     {
    46         scanf("%lld %lld",&a,&b);
    47         printf("Case #%d: %lld
    ",cnt++,solve(b)-solve(a-1));
    48     }
    49     return 0;
    50 }
  • 相关阅读:
    C++(四十)— C++中一个class类对象占用多少内字节
    C++(三十九) — 主函数中增加调试信息
    C++(三十八) — 继承方式、访问控制、构造和析构、虚继承
    ambari部署Hadoop集群(1)
    小波分析和多尺度几何分析
    正则化与矩阵范数
    设计模式之:创建型设计模式
    设计模式六大原则(详细)
    UML类关系(依赖,关联,聚合,组合,泛化,实现)
    SSD详解
  • 原文地址:https://www.cnblogs.com/henserlinda/p/4717710.html
Copyright © 2011-2022 走看看