zoukankan      html  css  js  c++  java
  • hdu 1011 Starship Troopers (树形背包dp)



    本文出自   http://blog.csdn.net/shuangde800


    题目链接 : hdu-1011

     

    题意

    有n个洞穴编号为1~n,洞穴间有通道,形成了一个n-1条边的树, 洞穴的入口即根节点是1。
    每个洞穴有x只bugs,并有价值y的金子,全部消灭完一个洞穴的虫子,就可以获得这个洞穴的y个金子.
    现在要派m个战士去找金子,从入口进入。每次只有消灭完当前洞穴的所有虫子,才可以选择进入下一个洞穴。
    一个战士可以消灭20只虫子,如果要杀死x只虫子,那么要x/20向上取整即(x+19)/20个战士。
    如果要获得某个洞穴的金子,必须留下足够杀死所有虫子的战士数量, 即(x+19)/20个战士,然后这些留下战士就不能再去其它洞穴
    其他战士可以继续走去其它洞穴,可以选择分组去不同的洞穴。
    战士只能往洞穴深处走,不能走回头路
    问最多能获得多少金子?



    思路

    这题一开始没有理解好题意,所以WA了多次,理解好题意就不难了。
    我们可以知道每个节点的花费cost(i) = (x(i)+19)/20。
    那么,
    f(i, j):表示i子树,用j个战士最多可以获得的价值。
    如果i有s个儿子节点,那么就形成了s组的物品,对每组物品进行分组背包。
    每一组可以选择派1,2...j-cost(i)个战士去,为什么最多是j-cost(i)?因为还要留下cost(i)个战士消灭当前洞穴的虫子。
    这样就可以得到状态转移了:

    f(i, j) = max { max{ f(i, j-k) + f(v, k) | 1<=k<=j-cost(i) } |  v是i的儿子节点 }

    这题要特别注意的是,如果是叶子节点,并且叶子节点的花费为0,那么要让他的花费变为1,因为必须派一个战士走向叶子节点才可以获得金子.


    代码

     






  • 相关阅读:
    favicon.ico在线制作,在线Favicon.ico制作转换工具
    素材之家,中国免费素材下载网站!下免费素材就到素材之家!
    visual assit 2010 2008均可用
    SQL server2008卸载出现重启怎么解决
    ping测试网络
    inndy_rop
    BJDCTF 2nd web
    [BJDCTF 2nd]one_gadget
    bjdctf_2020_babystack2
    堆溢出之unlink
  • 原文地址:https://www.cnblogs.com/pangblog/p/3271432.html
Copyright © 2011-2022 走看看