【解题报告】公司聚会

题目来源:vijos1418.
参考自:raoyu的题解(在第一面,往下拉一点)
其实这是一个在树上的01背包问题。这道题与经典的公司聚会不同,因为上司的定义由父结点改为了所有祖先。这样问题也由树形dp变为了01背包。由于题目中有一个非常重要的条件,“员工的编号会大于他的直接上司的编号”,我们可以直接循环而不用建立树结构。
设f[v,m]是以v为根的子树花费m元最大可以获得的兴奋指数。则在循环到v以前,f[v,m]表示以v为根的子树(不包括v)花费m元最大可以获得的兴奋指数;在循环到v时及以后,f[v,m]表示以v为根的子树(可能包括v,取决于取v的儿子们值大还是v的值大)花费m元最大可以获得的兴奋指数。

这次具体的解释写在注释里。

PS:这题数据范围很坑人,m最大109。我还以为是10^9打成了109。

AC代码

program vijos1418;
var i,j,k,n:longint;
    m:longint;
    c,e,fa:array[0..1024]of longint;
    f:array[0..1024,0..109]of longint;
function max(a,b:longint):longint;
begin
  if(a>b)then exit(a);
  exit(b);
end;
begin
    readln(n,m);
    for i:=2 to n do read(fa[i]);
    for i:=1 to n do read(c[i]);
    for i:=1 to n do read(e[i]);

    for i:=n downto 1 do begin//倒序进行,确保在更新每一个结点时,该节点的所有子节点都已经被更新过。
      for j:=c[i] to m do f[i,j]:=max(f[i,j],e[i]);//此时f[i,j]仍然表示以i为根的子树(不包括i)花费j元最大可以获得的兴奋指数,将其与自身兴奋指数比较,留下大者。

      for j:=m downto 0 do
        for k:=0 to j do
            f[ fa[i],j ]:=max(f[fa[i],j], f[fa[i],j-k]+f[i,k]);//这三行背包
    end;

    writeln(f[1,m]);
end.

另:
某神犇的AC结果:
某神犇的AC结果
我的AC结果:
我的AC结果
这差距怎么这么大0.0,莫非有什么更厉害的算法。以后再来研究。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值