zoukankan      html  css  js  c++  java
  • 部分DP总结

    一 背包:

    背包是比较基础但应用比较广泛的一类DP, 其主要类型包括01背包, 完全背包, 多重背包, 分组背包等;

    背包问题条件一般可以化为: 给定n个物品,每一个物品有一个价值,一个代价;

    01背包就是在给定上述条件下 (每个物品只能用一次)求代价S以内能得到的最大价值。

    01背包可以滚成一维,只不过枚举价值时应倒着枚举;

    完全背包就是01背包问题中的每个物品可以用任意多次, 和01背包的唯一区别就是枚举价值正着枚举就行了。

    多重背包就是01背包问题中的每个物品最多可以用给定次数次。

    对于多重背包问题的解决, 比较直接的思路是在和之前两个一样,不过就是多枚举一个用到的次数 (次数的枚举在物品和价值的枚举之间)。

    但是这样复杂度还是比较高的, 我们可以考虑如何优化。

    首先, 对于任意一个数k, 它可以拆成几个2的次幂的和;

    所以我们把每个物品能用的次数拆分成若干个(每个都是2的多少次幂,和为它本身)吗,直接当01背包转移

    这样在转移过程中,对于每一个物品,每个可能的用的次数都会被使用到吗,所以正确性是显然的;

    同时,我们也总共只要枚举 sigma (logCi)个物品, 复杂度显然也更优秀了;

    分组背包就是有N组物品,每组Ci个物品,每个物品都是和01背包的物品一样的条件;

    直接当01背包来做(只不过要多枚举一个组数,同时组数也是第一维状态,同时应注意物品的那层循环在最内层);同样的和01背包一样可以滚掉第一维;

    其实单调队列也可用来优化背包,但是我自己都还没学。。。就算了吧~~~~(>_<)~~~~

    几道背包的好题:BZOJ4272 挂饰 (01背包), Luogu1537 弹珠(二进制优化多重背包), Luogu1156 垃圾陷阱 (01背包吧。。反正蛮好的);

    二、区间DP 

    区间DP没那么多好讲的, 听Dalao讲区间DP一般难在优化, 然后蒟蒻认为一般区间DP还难在发现他是区间DP(可能是我太水了)。。

    直接贴几道好点的题目:Luogu1220关路灯, CF567FMausoleum(可以去Luogu上看宇智波鼬大佬的题解), UVA10559 Blocks (可以去Luogu上看 EMT__Mashiro 神犇的题解);

    三、树形DP

    怎么说呢 我也可以说刚刚入门啊!

    其主要的思想就是先递归DP其子节点,然后回溯时在对此节点进行转移即可。

    裸一点树形DP 没有上司的舞会 , 时态同步 。

    然后稍微进阶一点的是树形背包 就是在树形DP的形式下做背包问题,实际上也还是离不开上面的思想。

    入门的树形背包 选课。

    然后上面几道题都是在树上有明确转移方向的,也就是说他的根是给定的。

    那么对于不定根的题目呢??

    这类暴力的思想是直接对每一个点作为根跑一遍树形DP,那样复杂度是会多一个n的 ,显然不优。

    那么怎样来做呢?? 

    实际上这一类问题一般都可以发现一个共性,把他做根的DP值是与把其父亲节点做根的DP值是息息相关的。

    仔细思考我们可以发现 ,这之间一定存在这某种递推关系有父节点的DP答案能够推出他的答案,不需要再DP一遍!!

    为什么呢??

    因为整棵树的结果就可以看成一部分由以它本身为根的子树组成(这是DP出来了的), 另一部分就是剩下的;

    在把他换成根后,一部分的贡献已知, 另一部分的贡献就是他父亲的DP值减去它本身的贡献,两部分合起来就是以他为根的答案。

    这样的话, 我们只要任意选一点为根跑一遍DP, 在通过遍历树的方法自顶向下递推一下就可以了。

    暂时先写这一点点吧 。还有很多类型的DP都没有涉及到,希望以后能抓紧时间补上。

  • 相关阅读:
    javascript之instanceof原理
    x86之描述符表寄存器
    Mac之DTerm
    C的一些特性
    Mac i386 Operands and Addressing Modes
    shell之条件测试
    linux之dup&dup2
    javascript之this
    x86之段描述符
    进制转换
  • 原文地址:https://www.cnblogs.com/Bhllx/p/9751185.html
Copyright © 2011-2022 走看看