• 数位DP


    数位DP的题曾经写过,但是就是各种混乱不堪=w=

    这次写的记忆化搜索....

    AC BZOJ 1833

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42 
     43 //==============================================================================
     44 //==============================================================================
     45 //==============================================================================
     46 //==============================================================================
     47 
     48 
     49 struct Counter
     50 {
     51     ll a[10];
     52     
     53     Counter(const Counter&f){ memcpy(a,f.a,sizeof(a)); }
     54     Counter(){ memset(a,0,sizeof(a)); }
     55     
     56     ll&operator[](const int&k)
     57     { return a[k]; }
     58     
     59     Counter operator+(Counter f)
     60     {
     61         Counter c;
     62         for(int i=0;i<10;i++) c[i]=a[i]+f.a[i];
     63         return c;
     64     }
     65     
     66     Counter operator-(Counter f)
     67     {
     68         Counter c;
     69         for(int i=0;i<10;i++) c[i]=a[i]-f.a[i];
     70         return c;
     71     }
     72     
     73     Counter operator*(const ll&k) //这里注意..... 
     74     {
     75         Counter c;
     76         for(int i=0;i<10;i++) c[i]=a[i]*k;
     77         return c;
     78     }
     79     
     80     Counter operator+=(Counter f)
     81     { for(int i=0;i<10;i++) a[i]+=f.a[i]; return *this; }
     82     
     83     Counter operator=(Counter f)
     84     { memcpy(a,f.a,sizeof(a)); return *this; }
     85     
     86     void Output()
     87     { printf("%lld",a[0]); for(int i=1;i<10;i++) printf(" %lld",a[i]); }
     88 };
     89 
     90 ll Pow(ll a,ll b) //a^b
     91 { ll res=1; for(ll i=0;i<b;i++) res*=a; return res; }
     92 
     93 Counter cpr[10][20];
     94 bool cpu[10][20];
     95 Counter CountPre(ll v,ll dig) //from (v0..0) to (v99..9) 
     96 {
     97     Counter res;
     98     if(dig==0) { return res; }
     99     if(cpu[v][dig]) return cpr[v][dig];
    100     cpu[v][dig]=true;
    101     if(dig==1) { res[v]++; return cpr[v][dig]=res; }
    102     for(ll i=0;i<10;i++)
    103     res+=CountPre(i,dig-1);
    104     res[v]+=Pow(10,dig-1);
    105     return cpr[v][dig]=res;
    106 }
    107 
    108 Counter cpb[10][20];
    109 bool cbu[10][20];
    110 Counter CountBeg(ll v,ll dig)
    111 {
    112     Counter res;
    113     if(dig==0) { return res; }
    114     if(cbu[v][dig]) return cpb[v][dig];
    115     cbu[v][dig]=true;
    116     if(dig==1) { for(ll i=0;i<=v;i++) res[i]++; return cpb[v][dig]=res; }
    117     res+=CountBeg(9,dig-1);
    118     for(ll i=1;i<=v;i++)
    119     res+=CountPre(i,dig);
    120     return cpb[v][dig]=res;
    121 }
    122 
    123 
    124 
    125 ll v[20]; //digits divided.
    126 ll t=0;
    127 Counter GetCount(ll x) //Count from 0 to x.
    128 {
    129     Counter res;
    130     
    131     if(x<10)
    132     {
    133         for(ll i=0;i<=x;i++)
    134         res[i]++;
    135         return res;
    136     }
    137     
    138     if(x<100)
    139     {
    140         for(ll i=0;i<=9;i++)
    141         res[i]++;
    142         for(ll i=10;i<=x;i++)
    143         res[i/10]++,res[i%10]++;
    144         return res;
    145     }
    146     
    147     t=0;
    148     ll _k=x;
    149     while(_k!=0)
    150     v[t++]=_k%10,_k/=10;
    151     
    152     Counter base;
    153     
    154     res+=CountBeg(v[t-1]-1,t);
    155     base[v[t-1]]++;
    156     
    157     for(ll d=t-2;d>=0;d--) //deal with digit d+1.
    158     if(v[d]!=0)
    159     {
    160         res+=base*(Pow(10,d)*v[d]);
    161         for(ll i=0;i<v[d];i++) res+=CountPre(i,d+1);
    162         base[v[d]]++;
    163     }
    164     else base[0]++;
    165     
    166     if(x==0) res[0]++;
    167     else
    168     while(x!=0)
    169     res[x%10]++,x/=10;
    170     
    171     return res;
    172 }
    173 
    174 int main()
    175 {
    176     ll L=getll();
    177     ll R=getll();
    178     (GetCount(R)-GetCount(L-1)).Output();
    179 
    180     return 0;
    181 }
    View Code

    裸的数位DP.

    主要思路:

    将统计的所有数按照某个规则分解成许多组.

    一般从高位往低位扫,然后以当前位数-1作一个分割点.

    下面以数字 360734 作例子说明.

    要分成两个大的部分.

    第一部分: 0到299999 .这部分直接特殊处理.

    第二部分: 300000到360734 .这部分递推处理.

    第二部分的统计数可以继续进行分组:

    300000到359999 (当前第5位),

    360000 不进行分组(因为当前数位为0,当前第四位),

    360000到360699 (当前第三位),

    360700到360729 (当前第二位),

    360730到360733 (当前第一位),

    最后剩下 360734.

    计算结果,一般要搞到两个函数值:

    1.从 $0$ 到 $a*{10}^{dig}$ 的统计值 $B(0,dig)$ 程序中为 $CountBeg()$ 函数.

    2.从 $a*{10}^{dig}$ 到 $a*{10}^{dig}+({10}^{dig}-1)$ 的统计值(即,a00..00到a99..99) 程序中为 $CountPre()$ 函数. 

    然后根据这个函数值对每个分组进行统计.

    要注意的地方:

    1.某些地方要打longlong的别漏了.....

    2.搞清楚函数的参数的意义...位数加一减一什么的......

  • 相关阅读:
    Spring杂谈 | 什么是ObjectFactory?什么是ObjectProvider?
    一次相亲经历,我彻底搞懂了什么叫阻塞非阻塞,同步异步
    Spring杂谈 | 你真的了解泛型吗?从java的Type到Spring的ResolvableType
    Spring官网阅读(十二)ApplicationContext详解(中)
    Spring官网阅读(十一)ApplicationContext详细介绍(上)
    Spring官网阅读(十)Spring中Bean的生命周期(下)
    Spring官网阅读(九)Spring中Bean的生命周期(上)
    influxDB 0.9 C# 读写类
    使用HAProxy实现sql server读库的负载均衡
    influxdb基本操作
  • 原文地址:https://www.cnblogs.com/DragoonKiller/p/4423313.html
Copyright © 2020-2023  润新知