zoukankan      html  css  js  c++  java
  • [ZJOI2010]数字计数【数位DP】

    题目链接

       很明显的数位DP,但是为什么会有0分的情况呢?可能有这样的两种情况没有考虑到:

    1000000000000 1000000000000
    

      

    100 110
    

      

      首先,想到的是做一个差分的办法来解决这个问题,那么就是求0~X的这样的一个前缀0、1、2、3、…… 、9在数位中出现了多少次。很明显的,就是求每个数位上对应每个数所产生的贡献了,同时,前导零不能算进去。

      那么,如果没有前导零的时候,实际上贡献就比较的好算了,以它为中间的某个值的时候,后面有多少个数就是这个数位对应数的产生的贡献了。当然还要注意的一点是,如果它是作为前导零出现的,那么可能还不能把它更新进答案里面去,以它作为上限值(阈值)的时候,也是不能把它当作记忆化更新的。

      作为阈值的时候,答案不完整。

      存在前导零的时候,计数的个数还未更新到位,对后继答案有影响。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <string>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <limits>
     8 #include <vector>
     9 #include <stack>
    10 #include <queue>
    11 #include <set>
    12 #include <map>
    13 #include <bitset>
    14 #include <unordered_map>
    15 #include <unordered_set>
    16 #define lowbit(x) ( x&(-x) )
    17 #define pi 3.141592653589793
    18 #define e 2.718281828459045
    19 #define INF 0x3f3f3f3f
    20 #define HalF (l + r)>>1
    21 #define lsn rt<<1
    22 #define rsn rt<<1|1
    23 #define Lson lsn, l, mid
    24 #define Rson rsn, mid+1, r
    25 #define QL Lson, ql, qr
    26 #define QR Rson, ql, qr
    27 #define myself rt, l, r
    28 #define pii pair<int, int>
    29 #define MP(a, b) make_pair(a, b)
    30 using namespace std;
    31 typedef unsigned long long ull;
    32 typedef unsigned int uit;
    33 typedef long long ll;
    34 struct node
    35 {
    36     ll a[10], num; bool flag;
    37     node() { memset(a, 0, sizeof(a)); num = 0; flag = false; }
    38     friend node operator + (node e1, node e2)
    39     { for(int i = 0; i <= 9; i ++) e1.a[i] += e2.a[i]; return e1; }
    40     friend node operator - (node e1, node e2)
    41     { for(int i = 0; i <= 9; i ++) e1.a[i] -= e2.a[i]; return e1; }
    42 } dp[15][10];
    43 int dig[15];
    44 ll a, b;
    45 node dfs(int pos, int x, bool top, bool zero)
    46 {
    47     node ans, tmp;
    48     ll num = 0;
    49     if(pos <= 1) { ans.a[x] ++; ans.num = 1; return ans; }
    50     if(!top && dp[pos][x].flag) return dp[pos][x];
    51     int u = top ? dig[pos - 1] : 9;
    52     for(int i = 0; i <= u; i ++)
    53     {
    54         ans = ans + (tmp = dfs(pos - 1, i, top && (i == u), zero && (!i)));
    55         if(!zero) num += tmp.num;
    56     }
    57     ans.a[x] += num;
    58     ans.num = num;
    59     if(!top && !zero)
    60     {
    61         dp[pos][x] = ans;
    62         dp[pos][x].flag = true;
    63     }
    64     return ans;
    65 }
    66 int main()
    67 {
    68     scanf("%lld%lld", &a, &b); a --;
    69     for(int i = 1; i <= 14; i ++)
    70     {
    71         dig[i] = a % 10;
    72         a /= 10;
    73     }
    74     for(int i = 0; i <= 14; i ++) for(int j = 0; j <= 9; j ++) dp[i][j] = node();
    75     node x = dfs(14, 0, true, true);
    76     for(int i = 1; i <= 14; i ++)
    77     {
    78         dig[i] = b % 10;
    79         b /= 10;
    80     }
    81     for(int i = 0; i <= 14; i ++) for(int j = 0; j <= 9; j ++) dp[i][j] = node();
    82     node y = dfs(14, 0, true, true);
    83     node ans = y - x;
    84     for(int i = 0; i <= 9; i ++) printf("%lld%c", ans.a[i], i == 9 ? '
    ' : ' ');
    85     return 0;
    86 }
  • 相关阅读:
    HDU 5492 Find a path
    codeforce gym 100548H The Problem to Make You Happy
    Topcoder SRM 144 Lottery
    codeforce 165E Compatible Numbers
    codeforce gym 100307H Hack Protection
    区间DP总结
    UESTC 1321 柱爷的恋爱 (区间DP)
    HDU 4283 You Are the One (区间DP)
    HDU 2476 String painter (区间DP)
    UESTC 426 Food Delivery (区间DP)
  • 原文地址:https://www.cnblogs.com/WuliWuliiii/p/14135195.html
Copyright © 2011-2022 走看看