Noip 2003T3 加分二叉树

36 篇文章 0 订阅
18 篇文章 0 订阅

题目:

 加分二叉树

来源:

 Noip 2003T3

题目大意:

 在中序遍历为(1,2,3,…,n)的各种二叉树中,选出加分最高的一棵二叉树,输出最  高加分和对此二叉树的前序遍历。
       加分规则:任意棵子树subtree(也包含tree本身)的加分计算方法如下:
       subtree的左子树的加分*subtree的右子树的加分+subtree的根的分数
       若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数,不考虑  它的空子树。

数据范围:

 n<30、分值<100、结果不会超过4,000,000,000

样例:

 5

 5 7 1 2 10

145
3 1 2 4 5

做题思路:

 树型dp,f[l,r]=max{f[l,i-1]*f[i+1,r]+a[i](l<=i<=r)},还要输出前序遍历。。

 Root[l,r]表示l到r间的跟是root[l,r],然后递归输出

知识点:

 树型dp,树的遍历

var
 root:array[0..50,0..50]of longint;
 f:array[0..50,0..50]of int64;
 a:array[0..50]of longint;
 n,i:longint;
function dp(l,r:longint):int64;
var
 i:longint;
 t,max:int64;
begin
 iff[l,r]>=0 then exit(f[l,r]);{<记忆化>}
 if l=rthen{<到叶子了>}
  begin
  f[l,r]:=a[l];
  root[l,r]:=l;
  exit(f[l,r]);
  end;
 ifl>r then{<超过叶子了→空子树>}
  begin
  f[l,r]:=1;
  exit(f[l,r]);
  end;
 max:=0;
 fori:=l to r do{<枚举根>}
  begin
  t:=dp(l,i-1)*dp(i+1,r)+a[i];
   ift>max then
   begin
    max:=t;
    root[l,r]:=i;
    end;
  end;
 f[l,r]:=max;
 exit(f[l,r]);
end;
procedure print(l,r:longint); {<先序遍历,貌似题是逐字节的,反正保万一输出时还搞了下格式>}
begin
 ifl>r then exit;
 if(l=1)and(r=n) then write(root[l,r])
 else write(' ',root[l,r]);
 print(l,root[l,r]-1);
 print(root[l,r]+1,r);
end;
begin
 assign(input,'binary.in');reset(input);
 assign(output,'binary.out');rewrite(output);
 readln(n);
 fori:=1 to n do read(a[i]);
 readln;
 fillchar(f,sizeof(f),255);
 writeln(dp(1,n));
 print(1,n);
 close(input);close(output);
end.
题目来源: http://yt.tyvj.cn:8080/Problem_Show.asp?id=1040


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值