洛谷P1040 加分二叉樹

2021-08-29 05:12:22 字數 1473 閱讀 4044

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

$subtree$的左子樹的加分× subtreesubtreesubtree的右子樹的加分+$subtree$的根的分數。

若某個子樹為空,規定其加分為$1$,葉子的加分就是葉節點本身的分數。不考慮它的空子樹。

試求一棵符合中序遍歷為($1,2,3,…,n$)且加分最高的二叉樹$tree$。要求輸出;

(1)$tree$的最高加分

(2)$tree$的前序遍歷

輸入格式:

第$1$行:$1$個整數$n(n<30)$,為節點個數。

第$2$行:$n$個用空格隔開的整數,為每個節點的分數(分數$ <100$)。

輸出格式:

第$1$行:$1$個整數,為最高加分(ans ≤4,000,000,000 \le 4,000,000,000≤4,000,000,000)。

第$2$行:$n$個用空格隔開的整數,為該樹的前序遍歷。

輸入樣例#1:

5

5 7 1 2 10

輸出樣例#1:

145

3 1 2 4 5

這是一道樹形dp(幻燈片太惡意了。。。)

中序排列 = 左子樹 + 根節點 +  右子樹

然後我們就可以對於每個從i到j的節點的子樹列舉它的根節點k,不斷更新最大值同時把用g陣列儲存k值

一共有三種情況,空子樹,葉結點和正常點,所以我們可以列出乙個式子(你們想象一下有個大括號(我打不出來))

•a[i]      i=j(葉子)

•f [i,j]=       1        i=j+1(空子樹)                               

•max

i<=k<=j

•答案為f [1,n],時間複雜度為o(n3)。

接下來用遞迴輸出前序排列就行了

然後又ac了(鼓掌.jpg)

#include#include#include#includeusing namespace std;

int n;

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

const int q = 1e5 + 3;

int print(int l,int r)

}int main()

for(int l = 2;l <= n;l++)

}} }

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

print(1,n);

return 0;

}

洛谷 P1040 加分二叉樹

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

洛谷 P1040 加分二叉樹

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

洛谷p1040加分二叉樹

題目鏈結 洛谷p1040加分二叉樹 如下 用dp也可以做,這裡用的dfs 動態規劃還沒開始練題,就先用dfs 剪枝來寫吧 先序遍歷可以用遞迴快速實現 include includeusing namespace std int jd 10005 grade 1005 10005 root 1005 ...