NOIP2003 提高组 tyvj 1073 加分二叉树
描述 Description
设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整数),记第j个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:
subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数
若某个子树为主,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空
子树。
试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。要求输出;
(1)tree的最高加分
(2)tree的前序遍历
Delphi语言: 高亮代码由发芽网提供
program tyvj1073;
var f,tree:array[0..31,0..31] of longint;
i,j,n:longint;
procedure path(i,j:longint);
begin
if i=j then write(i,' ') else
begin
write(f[i,j],' ');
if f[i,j]-1>=i then path(i,f[i,j]-1);
if f[i,j]+1<=j then path(f[i,j]+1,j);
end;
end;
function dp(i,j:longint):longint;
var temp,k:longint;
begin
if tree[i,j]>0 then exit(tree[i,j]);
if i>j then exit(1);
if i<j then
for k:=i to j do begin
temp:=dp(i,k-1)*dp(k+1,j)+tree[k,k];
if temp>tree[i,j] then begin
tree[i,j]:=temp;f[i,j]:=k;
end;
end;
exit(tree[i,j]);
end;
beginreadln(n);
fillchar(tree,sizeof(tree),0);
for i:=1 to n do begin
read(tree[i,i]);
f[i,i]:=i;
end;
for i:=1 to n-1 do begin
tree[i,i+1]:=tree[i,i]+tree[i+1,i+1];
f[i,i+1]:=i;
end;
dp(1,n);
writeln(tree[1,n]);
path(1,n);
end.
浙公网安备 33010602011771号