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的前序遍历
输入格式 Input Format
    第1行:一个整数n(n<30),为节点个数。 第2行:n个用空格隔开的整数,为每个节点的分数(分数<100)。
样例输入 Sample Input [复制数据]
5 5 7 1 2 10 样例输出 Sample Output [复制数据] 145 3 1 2 4 5
输出格式 Output Format
    第1行:一个整数,为最高加分(结果不会超过4,000,000,000)。 第2行:n个用空格隔开的整数,为该树的前序遍历。
题解:红果果的树形DP  而且不用多叉转二叉...比较简单的说
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.

posted on 2012-10-06 18:20  馒头~blue  阅读(272)  评论(0)    收藏  举报

导航