加分二叉樹(區間動規或記憶化搜尋)

2021-07-15 15:14:07 字數 1146 閱讀 1061

設乙個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個用空格隔開的整數,為該樹的前序遍歷。

5

5 7 1 2 10

145

3 1 2 4 5

有乙個新的知識點就是先序遍歷:根,左,右,中序遍歷:左,根,右,後序遍歷:左,右,根。所以題中給的是中序遍歷之後的點,那麼它平鋪起來的左右就是它的左右兒子,就可以用區間動規處理,但是這裡面用到的f陣列的i,j表示的含義就不相同了,表示的都是端點。同時還需要列舉情況如果沒有左兒子或者右兒子的情況。這道題還可以用記憶化搜尋來實現。

記憶化搜尋

#include

using namespace std;

int a[50],f[50][50],g[50][50];

int dp(int l,int r)

} return f[l][r];

}void print(int a,int b)

int main()

for(int len=2;len<=n;++len)//不管i,j表示什麼含義,最外層迴圈一定是列舉長度

else if (f[i][i]+f[i+1][j] < f[i][j-1]+f[j][j])//沒有右兒子

//左右兒子都有

for(k=i+1;k<=j-1;++k)}}

}printf("%i64d\n",f[1][n]);

print(1,n);

return 0;

}

加分二叉樹 區間DP,記憶化搜尋)

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

codevs 1090 加分二叉樹(記憶化搜尋)

1090 加分二叉樹 2003 年noip 全國聯賽提高組 時間限制 1 s 空間限制 128000 kb 題目等級 鑽石 diamond 題目描述 description 設乙個n個節點的二叉樹tree的中序遍歷為 l,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數...

區間DP 加分二叉樹

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