題目描述 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的前序遍歷
現在,請你幫助你的好朋友xz設計乙個程式,求得正確的答案。
輸入描述 input description
第1行:乙個整數n(n
<=30),為節點個數。
第2行:n個用空格隔開的整數,為每個節點的分數(分數<=100)
輸出描述 output description
第1行:乙個整數,為最高加分(結果不會超過4,000,000,000)。
第2行:n個用空格隔開的整數,為該樹的前序遍歷。
樣例輸入 sample input 5
5 7 1 2 10
樣例輸出 sample output
1453 1 2 4 5
資料範圍及提示 data size & hint
n(n<=
30)
分數<=100
題解:這是一道區間型dp,特別的地方是需要加上乙個確定其範圍內的father節點的陣列。
因為題目要求樹的中序遍歷為1.2.3......n,所以對於乙個節點i,其左邊的那些節點,必定為它的左兒子或其祖先的兒子。
a陣列儲存分數。
狀態:dp[i][j]表示在i至j的範圍內的最優解,father[i][j]表示當i至j為最優解時的父親節點(前序遍歷有用)。
方程:dp[i][j]=max(i<=k<=j)記得同時在必要的時候更新father[i][j]。
#include #include #include #include #include using namespace std;int n,a[40],dp[40][40],father[40][40],shunxu[40],shu=0;
void find(int le,int ri);
int main()
for(int kuan=2;kuan<=n;kuan++)
shunxu[++shu]=father[le][ri];
find(le,father[le][ri]-1);
find(father[le][ri]+1,ri);
}
NOIP 2003 加分二叉樹
問題描述 設乙個n個節點的二叉樹tree的中序遍歷為 l,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第j個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 su...
NOIP 2003 加分二叉樹
評測傳送 這個題可以記憶化搜尋做的。注意邊界條件。對於先序遍歷,遞迴就可以了 在dfs的時候用乙個陣列記錄根節點就可以了 include include include include include include define ll long long using namespace std i...
NOIP2003 加分二叉樹題解
設乙個n 個節點的二叉樹t 的中序遍歷為 1,2,3,n 其中數字 1,2,3,n 為節點編號。每個節點都有乙個分數 均為正整數 記第j 個節點的分數為dj。二叉樹t 及它的每個子樹都有 乙個加分,任意一棵子樹s 包括t 本身 的加分等於s 的左子樹的加分 s 的右子樹的加分 s的根的分數。若某棵子...