zoukankan      html  css  js  c++  java
  • 数位DP 入门学习详解

    数位DP

    什么是数位DP

    数位DP是DP的一种,顾名思义,按每一个数位来进行DP。

    什么时候使用

    题目的要求与一个数字相关,并且它能通过每一个数位来进行转移。
    例题:求所有 n n n位数中能被 m m m整除的数的个数。

    怎么使用

    一般的DP是多维的,首先会有一维表示的是当前到了第几位,通常情况这一维可以使用滚动。
    其它的就是根据题目的实际要求了,如例题就需要一维来记录除以 m m m的余数。
    以例题为例,我们来讲讲数位DP怎么实现。

    状态与转移

    我们设 f [ i ] [ j ] f[i][j] f[i][j]表示当前到了第 i i i位,除以 m m m的余数为 j j j的方案数。
    一般是从高位往低位DP,因为最高位不能为 0 0 0,所以我们对 i = 1 i=1 i=1的情况先处理好:
    f [ 1 ] [ i m o d    m ] = 1 ( 1 ≤ i ≤ 9 ) f[1][i\mod m]=1(1≤i≤9) f[1][imodm]=1(1i9)

    接着我们用第 i i i位的状态去更新第 i + 1 i+1 i+1位的状态,每次枚举当前在第 i + 1 i+1 i+1位加入 k k k
    想想怎么转移?
    对于当前的余数 j j j,在末尾加入了 k k k,余数变成什么?
    根据同余的性质,我们自然可以得到:余数变成了 ( j ∗ 10 + k ) m o d    m (j*10+k)\mod m (j10+k)modm
    所以,状态转移方程如下:

    f [ i + 1 ] [ ( j ∗ 10 + k ) m o d &ThinSpace;&ThinSpace; m ] + = f [ i ] [ j ] ( 1 ≤ i &lt; n , 0 ≤ j &lt; m , 0 ≤ k ≤ 9 ) f[i+1][(j*10+k)\mod m]+=f[i][j](1≤i&lt;n,0≤j&lt;m,0≤k≤9) f[i+1][(j10+k)modm]+=f[i][j](1i<n0j<m0k9)

    最后的答案是什么?
    首先,第一维自然是 n n n,那么第二维取什么值呢?
    显而易见,要求是 m m m的倍数,所以第二维是 0 0 0
    综上所述,最后的答案是 f [ n ] [ 0 ] f[n][0] f[n][0]

    更多拓展

    【数位DP】JZOJ 5831. 【NOIP提高A组模拟2018.8.18】 number

    哈哈哈哈哈哈哈哈哈哈
  • 相关阅读:
    深入理解HTTP协议及原理分析
    如何提高php应用的性能?
    PHP的网站主要攻击方式有哪些?
    五种常见的 PHP 设计模式
    排序算法之插入排序类
    排序算法之交换排序类
    Redis之Zset
    Redis之Set
    Redis之List
    Redis之Hash
  • 原文地址:https://www.cnblogs.com/LZA119/p/13910114.html
Copyright © 2011-2022 走看看