設乙個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個用空格隔開的整數,為該樹的前序遍歷。
名帶二叉樹的區間dp
在一段區間內列舉根節點,那麼f[
i][j
] 表示i至j間合併成一棵樹的最大加分 f[
i][j
]=max(f[
i][k
−1]∗
f[k+
1][j
]+f[
k][k
])(i
≤k≤j
) 當一棵樹只有左子樹或只有右子樹時,即k與i或j重合,特殊判斷一下就行了 用r
[i][
j]記錄合併i至j區間的根,輸出的時候dfs
#include
#include
#define rep(i, a, b) for (int i = a; i <= b; i ++)
#define fill(x, t) memset(x, t, sizeof(x))
#define n 101
int num[n], f[n][n], r[n][n];
using
namespace
std;
inline
int read()
ch = getchar();
}while (ch >= '0' && ch <= '9')
return x * v;
}inline
int max(int x, int y)
inline
int dfs(int x, int y)
printf("%d ", fa);
if (x < fa)
if (y > fa)
}int main(void)
rep(t, 1, n)else
if (k == j)
if (cal > f[i][j])}}
}printf("%d\n", f[1][n]);
dfs(1, n);
return
0;}
洛谷1040 加分二叉樹
題目描述 設乙個n個節點的二叉樹tree的中序遍歷為 1,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 su...
洛谷 1040 加分二叉樹
設乙個nn個節點的二叉樹tree的中序遍歷為 1,2,3,n1,2,3,n 其中數字1,2,3,n1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第ii個節點的分數為di,treedi,tree及它的每個子樹都有乙個加分,任一棵子樹subtreesubtree 也包含treetree本...
洛谷 加分二叉樹,P1040
dp,整個樹是由中序遍歷1,n構成的,score i j 記錄的是中序遍歷為i,i 1,j 1,j的子樹的最高加分。tag i j 記錄的是中序遍歷為i j的子樹的根節點,用於重建前序遍歷。那最高加分的結果對應的是score 1 n dp的思路就是,先設定只有乙個節點的子樹的初值,即只含有根節點的子...