NOIP2003 提高組 加分二叉樹

2021-08-19 04:27:37 字數 1304 閱讀 8517

設乙個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

思路:看到題目,以為是二叉樹,竟然要根據中序遍歷求前序遍歷!(心想這怎麼可能)後來經過大佬指點,發現記憶化搜尋就可以。

**:

#include#include#include#include#define loop( i, a, b )	for( int i = a; i <= b; i++ )

using namespace std;

//root[i][j]為i、j兩個節點的根節點,f陣列存分數。

int n, v[10010], root[2002][2002], f[2002][2002];

int hahasearch( int l, int r )

} return f[l][r];

}//求先序遍歷

void find_tree( int l, int r )

printf( "%d ", root[l][r] ); //輸出節點。

//從根節點向左向右

find_tree( l, root[l][r] - 1 );

find_tree( root[l][r] + 1, r );

}int main()

int ans = hahasearch( 1, n );

printf( "%d\n", ans );

find_tree( 1, n );

return 0;

}

NOIP2003提高組 加分二叉樹

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

NOIP 2003 提高組 複賽 加分二叉樹

noip 2003 提高組 複賽 加分二叉樹 1.樣例1分析是關鍵 輸入 5 5 7 1 2 10 輸出 145 3 1 2 4 5 1 2 3 4 5 中序遍歷 3 1 2 4 5 前序遍歷 分析可得二叉樹如下圖 3 1 4 2 5 3的左子樹計算1 7 5 12 3的右子樹計算1 10 2 12...

NOIP 2003 加分二叉樹

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