加分二叉樹

2022-05-26 06:48:10 字數 1195 閱讀 1617

時間限制: 1 sec  記憶體限制: 512 mb

題目描述

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

記subtree的左子樹加分為l,右子樹加分為r,subtree的根的分數為a,則subtree的加分為:l*r+a

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

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

要求輸出:

1.tree的最高加分;

2.tree的前序遍歷。

輸入第一行乙個整數n表示節點個數;

第二行n個空格隔開的整數,表示各節點的分數。

輸出第一行乙個整數,為最高加分b;

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

樣例輸入

5

5 7 1 2 10

樣例輸出

145

3 1 2 4 5

提示對於100%的資料,n<30,b<100,結果不超過4e9。

我們老師把這道題放到了樹形dp裡,然而我用樹形dp套路肝了兩個多小時都沒搞出來,然而有乙個同學說這是區間dp,

我才恍然大悟,然後用不到1h就寫完ac了

1.tree的最高加分:中序遍歷有個特點就是假設節點x為根,則對於乙個節點y,如果y>x則y在x的右子樹上,如果x>y則

y在x的左子樹上,

這樣我們對於每個序列都能很輕鬆地找到它的最優的根與這最優的值,最後輸出最優的值即可

2.tree的前序遍歷:這個比起第乙個就簡單多了,直接乙個遞迴找子節點就好了

**如下:

#includeusing namespace std;

int n;

int v[31];

int dp[31][31];

int root[31][31];

int dfs(int l,int r)

if(l==r)

if(rdp[l][r])

}return dp[l][r];

}void print(int l,int r)

{ if(r

加分二叉樹

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

加分二叉樹

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

加分二叉樹

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