加分二叉樹 洛谷1040 dp

2021-07-26 04:50:15 字數 1480 閱讀 2987

設乙個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的思路就是,先設定只有乙個節點的子樹的初值,即只含有根節點的子...