zoukankan      html  css  js  c++  java
  • [学习笔记] 数位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;
  • 相关阅读:
    常用正则表达式实例
    java doc注释
    不让WINDOWS检测硬盘的方法
    maven eclipse插件使用问题解决
    indexof 和 indexofany有什么区别
    asp.net验证码
    C#里如何把数据库里的日期显示为只包含年月日
    雷人的发现 谷歌浏览器三大不为人知的秘密
    三层架构实例
    正则表达式30分钟入门教程
  • 原文地址:https://www.cnblogs.com/WR-Eternity/p/9928602.html
Copyright © 2011-2022 走看看