zoukankan      html  css  js  c++  java
  • [vijos P1180] 选课

    这一周竟然都没好好码题目,不过至少把这题的树形DP给摸了个大概。吐槽一下自己,递归已经基本不会用了…QAQ!按老师的话来说“太危险了!”

    此题用到多叉树转二叉树,左孩子是真正意义的孩子(先修完自己才能修左孩子),右孩子是同辈。着实是一个好方法,同时我也不知道多叉树该怎么写,多套个循环扫?Anyway转二叉搞会了。

    f[x,y]表示,以x为根节点的子树,上y节课可以修到的最大学分。(没看解题前我的思路是,f[x,y]表示从1~x中选y节课可以得到的最大学分QAQ错错错)

    最后犯的小错误是在DP子函数里面,for k:=0 to num-1,一开始把0写成1了,所以导致所有的答案都偏小一些。写成1的话,就没把c[root]+f[r[root],num-1]的情况给算进去。

    DP就是精简,但是递推方程就是难想,想象力得多丰富才想得到,出题者又得多厉害出得出这种题。

    program vijos_p1180;
    var f:Array[0..301,0..301] of longint;
        l,r,c,p:array[0..301] of integer;
        n,m,i,d,t,tt,root,ans:integer;
        flag:boolean;
    function max(a,b:integer):integer;
    begin
      if a>b then exit(a) else exit(b);
    end;
    function dp(root,num:integer):integer;
    var k,t:integer;
    begin
      t:=0;
      if (root=0) or (num=0) then exit(0);
      if f[root,num]>0 then exit(f[root,num]);
      f[root,num]:=dp(r[root],num);
      if (num=1) and (c[root]>f[root,num]) then f[root,num]:=c[root];
      for k:=0 to num-1 do
        begin
          t:=dp(l[root],k)+dp(r[root],num-k-1)+c[root];
          if t>f[root,num] then f[root,num]:=t;
        end;
      dp:=f[root,num];
    end;
    
    begin
      readln(n,m);
      flag:=false;
      for i:=1 to n do
        begin
          readln(d,c[i]);
          p[i]:=d;
          if (d=0) and (flag=false) then
            begin
              flag:=true;
              root:=i;
            end;
          if l[d]=0 then l[d]:=i
          else begin
                 t:=l[d];
                 while r[t]<>0 do
                   t:=r[t];
                 r[t]:=i;
               end;
        end;
      ans:=dp(root,m);
      writeln(ans);
    end.
    选课

    测试数据 #0: Accepted, time = 0 ms, mem = 1096 KiB, score = 20

    测试数据 #1: Accepted, time = 15 ms, mem = 1092 KiB, score = 20

    测试数据 #2: Accepted, time = 15 ms, mem = 1092 KiB, score = 20

    测试数据 #3: Accepted, time = 46 ms, mem = 1092 KiB, score = 20

    测试数据 #4: Accepted, time = 62 ms, mem = 1096 KiB, score = 20

    P.S. 为什么别人都是0ms难道我写的有什么问题么,看了别人代码感觉我多叉转二叉写麻烦了,不过我完全按照自己想象力去写的。

    P.S.2 此题也是tyvj 1051 选课。tyvj感觉好久没人维护了呀…毕竟是自己最开始用的oj感情还是深的T^T!

  • 相关阅读:
    Java代码实现依赖注入
    Linux shell脚本的字符串截取
    Android教程:wifi热点问题
    Android framework层实现实现wifi无缝切换AP
    http mimetype为multipart/x-mixed-replace报文
    Realtek 8192cu 支持 Android Hotspot 软ap
    http协议详解
    Android 在一个程序中启动另一个程序(包名,或者类名)
    linux定时器
    进程与线程的一个简单解释(转)
  • 原文地址:https://www.cnblogs.com/Sky-Grey/p/3601305.html
Copyright © 2011-2022 走看看