設乙個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輸出樣例#1:複製5 7 1 2 10
145讓我們求中序遍歷符合12345的樹中,最大加分的哪乙個樹,這裡有乙個突破點:中序遍歷符合12345這樣的樹,那麼任何乙個結點它的左孩子結點一定比它小,右孩子結點一定比它大,這樣我們就可以1~n列舉它的根結點,像線段樹一樣,只不過我們用rot[i][j]來儲存區間i到j的根結點,用opt[i][j]來儲存區間i到j的最大加分3 1 2 4 5
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 的左子...