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

    哈哈哈哈哈哈哈哈哈哈
  • 相关阅读:
    单臂路由
    C#同步、异步编程
    Grid控件
    使用WrapPanel和DockPanel
    使用StackPanel进行简单地布局
    WPF布局
    SQL update 多表连接方法
    创建一个自定义的Application类
    Application全局应用程序类
    XAMl使用其他命名空间中的类型及加载和编译
  • 原文地址:https://www.cnblogs.com/LZA119/p/13910114.html
Copyright © 2011-2022 走看看