• [学习笔记] 数位DP的dfs写法


    跟着洛谷日报走,算法习题全都有!

    嗯,没错,这次我也是看了洛谷日报的第84期才学会这种算法的,也感谢Mathison大佬,素不相识,却写了一长篇文章来帮助我学习这个算法。

    算法思路:

    感觉dfs版的数位dp还是挺简单的,直接dp然后递推统计答案的那种比它搞脑子多了。

    在dfs版本中,我们需要特别注意的地方有两个:

    1、是否贴上界:

    这是个啥呢?

    很简单,给大家举个栗子,假如我们要求解1-12345这段区间,如果我们已经做了3位,而前三位正好是123,那么我们第4位就只能取0-5,否则我们就可以取0-9。

    2、有没有前导零:

    这有为啥要特殊记呢?

    因为前导零会影响我们对合法方案的统计。

    当现在的状态有前导零,或者贴上界的时候我们就不能记忆化,因为它们是与别的状态不同的,不同之处就是上面讲的那些啦。

    dfs模板:

    function dfs(pos,...,lead,flag:Longint):int64;
    var
        res:int64;
        i,limit:Longint;
    begin
    //pos:当前在做第几位。
    //lead:0/1 有/没有 前导零
    //flag:0/1 是/否 贴上界 if pos>len then exit(...); ...... ...... //各种优化 if (dp[pos][...]<>-1)and(lead+flag=0) then exit(dp[pos][...]); //记忆化 if flag=1 then limit:=a[len-pos+1] else limit:=9; //最高枚举到几 res:=0; for i:=0 to limit do res:=res+dfs(pos+1,...,...,ord((lead=1)and(i=0)),ord((flag=1)and(i=limit))); if lead+flag=0 then dp[pos][...]:=res; dfs:=res; end; function part(x:int64):int64; //数位分离 begin len:=0; part:=0;while x>0 do begin inc(len); a[len]:=x mod 10; x:=x div 10; end;
    part:=dfs(1,...,1,1);
    end;
  • 相关阅读:
    2019ICPC上海站
    “浪潮杯”第九届山东省ACM大学生程序设计竞赛重现赛(2018)
    集合问题
    后缀数组
    141. 周期(KMP)
    求和(矩阵快速幂)
    大数(KMP)
    1270: [蓝桥杯2015决赛]完美正方形
    AC自动机
    8.26作业
  • 原文地址:https://www.cnblogs.com/WR-Eternity/p/9928602.html
Copyright © 2020-2023  润新知