設乙個n個節點的二叉樹tree的中序遍歷為(l,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個用空格隔開的整數,為該樹的前序遍歷。
55 7 1 2 10
每個測試點1s1453 1 2 4 5
noip2003第三題
都說是dp。。。我開始想的是暴力。。。然後瞎寫了寫怎麼就寫了個dp。。。。
我的想法是因為n最多只有30個。。那麼我們可以列舉根節點,然後分別在根的兩邊進行同樣的操作。。。然後就變成了列舉區間列舉節點。。。
不過列舉區間的時候要記住從後往前。。。
4 #include5 #include6 #include7 #include8 #include9 #include10 #includeview code11 #include12 #include13 #include14 #include
15#define inf 1000000000
16#define maxn 100+5
17#define maxm 100+5
18#define eps 1e-10
19#define ll long long
20#define for0(i,n) for(int i=0;i<=(n);i++)
21#define for1(i,n) for(int i=1;i<=(n);i++)
22#define for2(i,x,y) for(int i=(x);i<=(y);i++)
23#define for3(i,x,y) for(int i=(x);i>(y);i--)
24#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
25using
namespace
std;
26int
read()
2730
while(ch>='
0'&&ch<='9')
31return x*f;32}
33int
f[maxn][maxn],a[maxn],root[maxn][maxn];
34void output(int l,int
r)40
intmain()55}
56}57 printf("
%d\n
",f[1
][n]);
58 output(1
,n);
59return0;
60 }
加分二叉樹
描述 設乙個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...