題意:設乙個n個節點的二叉樹tree的中序遍歷為(l,2,3,…,n),其中數字1,2,3…,n為節點編號。
每個節點都有乙個分數(均為正整數),記第j個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree(也包含tree本身)的加分計算方法如下:
subtree的左子樹的加分× subtree的右子樹的加分+subtree的根的分數
若某個子樹為主,規定其加分為1,葉子的加分就是葉節點本身的分數。不考慮它的空子樹。
試求一棵符合中序遍歷為(1,2,3,…,n)且加分最高的二叉樹tree。要求輸出;
(1)tree的最高加分
(2)tree的前序遍歷
分析:1.題目中明確要求生成的樹其中序遍歷為1,2,3....n,根據這個我們可以知曉對於a1,a2,a3,a4...ai....an來說,若ai為根,則a1,a2....ai-1在為ai的左子樹,ai+1....an為ai的右子樹,所以這給我們進行區間動態規劃成為了可能
2.區間動態規劃,用遞迴進行書寫簡單且易於理解
3.路徑的記憶,定義乙個路徑陣列,若更新dp值得時候,也更新路徑的根節點
4.路徑列印,由於要求前序遍歷,所以先輸出,再分別遞迴左子樹,右子樹
5.錯誤點:在書寫**的時候,dfs(x,i-1)*dfs(i+1,y),書寫太粗心寫漏了乙個dfs,導致debug了很久都沒有找出錯誤來。
#include#include#include
using
namespace
std;
#define ll long long
const
int inf=0x7fffffff
;const
int mn=50
;ll dp[mn][mn];
intpath[mn][mn];
intnum[mn];
intn;
intflag;
ll dfs(
int x,int
y)
if(dp[x][y]!=-1) return
dp[x][y];
if(x==y)
dp[x][y]=0
;
for(int i=x; i<=y; i++)
}return
dp[x][y];
}void print(int x,int
y)int
main()
return0;
}
479 加分二叉樹
原題傳送門 設乙個n個節點的二叉樹tree的中序遍歷為 1,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 s...
加分二叉樹
描述 設乙個n個節點的二叉樹tree的中序遍歷為 l,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 subt...
加分二叉樹
設乙個n個節點的二叉樹tree的中序遍歷為 l,2,3,n 其中數字1,2,3,n為節點編號。每個節點都有乙個分數 均為正整數 記第i個節點的分數為di,tree及它的每個子樹都有乙個加分,任一棵子樹subtree 也包含tree本身 的加分計算方法如下 subtree的左子樹的加分 subtree...