設乙個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:
55 7 1 2 10
輸出樣例#1:
1453 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...