乙個子樹內的前序遍歷序是連續的,
於是可以設 f[i
,j]f[i, j]
f[i,j]
表示以 i
ii 為根的子樹, 子樹末節點編號為 j
jj 時的方案數,
狀 態轉
移:f[
i,j]
=∑k=
ijf[
i,k]
×f[k
+1,j
]狀態轉移: f[i, j] = \sum\limits_^ f[i, k] \times f[k+1, j]
狀態轉移:f
[i,j
]=k=
i∑j
f[i,
k]×f
[k+1
,j] .
考慮怎麼滿足題目的限制條件, 設左子樹的中序遍歷編號為 a
aa, 右子樹為 c
cc, 根節點為 bbb,
中序遍歷的要求是: a
<
ba < b
a<
b, a
<
ca < c
a<
c, b
<
cb < c
b由於前序遍歷編號是連續的, 所以可以考慮使用二維矩陣字首和判斷轉移是否合法.
具 體來
說具體來說
具體來說
:若存在限制 u,v
u, v
u,v, 則令矩陣陣列 a[u
,v]=
1a[u, v] = 1
a[u,v]
=1, 表示中序遍歷中 u
uu 的編號 要 小於 v
vv 的 編號,
於是對於前面提到的三個限制, 只需要
若上方有乙個矩陣含有 1
11, 說明狀態轉移不合法, 不予以轉移 .
使用遞迴實現 .
#include
#define reg register
intread()
while
(isdigit
(c)) s = s*
10+ c-
'0', c =
getchar()
;return s * flag;
}const
int maxn =
305;
const
int mod =
1e9+7;
int n;
int m;
int a[maxn]
[maxn]
;int f[maxn]
[maxn]
;int
calc
(int x1,
int y1,
int x2,
int y2)
intsolve
(int i,
int j)
return f[i]
[j]= res;
}void
work()
a[u]
[v]=1;
}for
(reg int i =
1; i <= n; i ++
)for
(reg int j =
1; j <= n; j ++
) a[i]
[j]+
= a[i-1]
[j]+ a[i]
[j-1
]- a[i-1]
[j-1];
printf
("%d\n"
,solve(1
, n));
}int
main()
束縛二叉樹 樹形dp
乙個子樹內的前序遍歷序是連續的,於是可以設 f i j f i,j 表示以 i i 為根的子樹,子樹末節點編號為 j j 時的方案數,狀態 轉移 f i,j k ijf i,k f k 1,j 狀態 轉移 f i,j k i j f i,k f k 1 j 考慮怎麼滿足題目的限制條件,設左子樹的中序...
樹形dp 加分二叉樹 11 05 15
題目 加分二叉樹 問題描述 設乙個n 個節點的二叉樹 tree 的中序遍歷為 l,2,3,n 其中數字 1,2,3,n 為節點編號。每個節點都有乙個分數 均為正整數 記第 i個節點的分數為di,tree 及它的每個子樹都有乙個加分,任一棵子樹 subtree 也包含 tree 本身 的加分計算方法如...
樹形dp技巧,多叉樹轉二叉樹
今天覆習樹形dp時發現一道比較古老的題,叫選課,是樹形dp的一道基礎題,也是多叉樹轉二叉樹應用的模版題 多叉樹轉二叉樹的應用非常廣泛,因為如果乙個節點的兒子太多,乙個乙個存下來不方便去查詢,並且會增加複雜度,但是這裡我們就有乙個o n 的複雜度的方法把多叉樹轉換為二叉樹,轉換成二叉樹後就更方便查詢,...