洛谷 P1040 加分二叉樹

2021-07-27 16:30:01 字數 2106 閱讀 3983

題目描述

設乙個n個節點的二叉樹tree的中序遍歷為(1,2,3,…,n),其中數字1,2,3,…,n為節點編號。每個節點都有乙個分數(均為正整數),記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree(也包含tree本身)的加分計算方法如下:

subtree的左子樹的加分× subtree的右子樹的加分+subtree的根的分數。

若某個子樹為空,規定其加分為1,葉子的加分就是葉節點本身的分數。不考慮它的空子樹。

試求一棵符合中序遍歷為(1,2,3,…,n)且加分最高的二叉樹tree。要求輸出;

(1)tree的最高加分

(2)tree的前序遍歷

輸入輸出格式

輸入格式:

第1行:乙個整數n(n<30),為節點個數。

第2行:n個用空格隔開的整數,為每個節點的分數(分數<100)。

輸出格式:

第1行:乙個整數,為最高加分(結果不會超過4,000,000,000)。

第2行:n個用空格隔開的整數,為該樹的前序遍歷。

輸入輸出樣例

輸入樣例#1:

5 5 7 1 2 10

輸出樣例#1:

145

3 1 2 4 5

分析:樹形dp模版題。

**:

const

maxn=30;

var f,r:array[1..maxn,1..maxn] of longint;

a:array[1..maxn] of longint;

n:longint;

procedure

init;

var i:longint;

begin

readln(n);

for i:=1

to n do

read(a[i]);

end;

procedure

preorder

(p1,p2:longint);

begin

if p2>=p1

then

begin

write(r[p1,p2],' ');

preorder(p1,r[p1,p2]-1);

preorder(r[p1,p2]+1,p2);

end;

end;

procedure

dp;var

i,j,k,t,max:longint;

begin

for i:=1

to n do

begin

f[i,i]:=a[i];

r[i,i]:=i;

end;

for i:=1

to n-1

dobegin

f[i,i+1]:=a[i]+a[i+1];

r[i,i+1]:=i;

end;

for j:=2

to n-1

dofor i:=1

to n-j do

begin

max:=f[i,i]+f[i+1,i+j];

r[i,i+j]:=i;

for k:=1

to j do

begin

t:=f[i+k,i+k]+f[i,i+k-1]*f[i+k+1,i+j];

if t>max

then

begin

max:=t;

r[i,i+j]:=i+k;

end;

end;

t:=f[i,i+j-1]+f[i+j,i+j];

if t>max

then

begin

max:=t;

r[i,i+j]:=i+j+1;

end;

f[i,i+j]:=max;

end;

end;

procedure

print;

begin

writeln(f[1,n]);

preorder(1,n);

end;

begin

init;

dp;print;

end.

洛谷 P1040 加分二叉樹

題目描述 設乙個n個節點的二叉樹tree的中序遍歷為 1,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 su...

洛谷P1040 加分二叉樹

設乙個 n 個節點的二叉樹tree的中序遍歷為 1,2,3,n 其中數字 1,2,3,n 為節點編號。每個節點都有乙個分數 均為正整數 記第 i 個節點的分數為 di,tree 及它的每個子樹都有乙個加分,任一棵子樹 subtree 也包含 tree 本身 的加分計算方法如下 subtree 的左子...

洛谷p1040加分二叉樹

題目鏈結 洛谷p1040加分二叉樹 如下 用dp也可以做,這裡用的dfs 動態規劃還沒開始練題,就先用dfs 剪枝來寫吧 先序遍歷可以用遞迴快速實現 include includeusing namespace std int jd 10005 grade 1005 10005 root 1005 ...