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 }
  • 相关阅读:
    开发笔记
    PHP的重载及魔术方法
    网站飘窗效果
    asp.net 导入Excel记录到数据库中(转载)
    safari打不开该网页 因为网址无效(解决办法)
    使用join()方法 分隔拆分后的数组
    面向新手的Web服务器搭建——IIS的搭建(转载)
    ueditor上传大容量视频报http请求错误的解决方法(转载)
    表格中针对大段说明文字加一个弹出层
    JS禁止右键及禁止选中文本
  • 原文地址:https://www.cnblogs.com/WuliWuliiii/p/14135195.html
Copyright © 2011-2022 走看看