洛谷P1040 加分二叉樹

2021-09-13 13:29:16 字數 1472 閱讀 1131

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

subtreesubtree的左子樹的加分× subtreesubtree的右子樹的加分+subtreesubtree的根的分數。

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

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

(1)tree的最高加分

(2)tree的前序遍歷

輸入格式:

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

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

輸出格式:

第1行:1個整數,為最高加分(ans \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

讓我們求中序遍歷符合12345的樹中,最大加分的哪乙個樹,這裡有乙個突破點:中序遍歷符合12345這樣的樹,那麼任何乙個結點它的左孩子結點一定比它小,右孩子結點一定比它大,這樣我們就可以1~n列舉它的根結點,像線段樹一樣,只不過我們用rot[i][j]來儲存區間i到j的根結點,用opt[i][j]來儲存區間i到j的最大加分

code:

#include#define lom long long 

#define m 35

using namespace std;

int rot[m][m],a[m],opt[m][m],n;

//rot[i][j]存放區間i到j的根結點,a存放輸入序列

//opt[i][j]存放區間i到j的最大分

int deep(int l,int r)

if(opt[l][r]) return opt[l][r];

//如果區間lr已經被求出來了,直接返回這個區間的最優解

int ans=0,num;

for(int k=l;k<=r;k++)//列舉l r的根結點 }

rot[l][r]=num;//將最優根結點存入這個區間的rot

return opt[l][r]=ans;//將最大分存入這個區間的opt

}void print(int l,int r)//前序遍歷

洛谷 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 加分二叉樹

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