n个节点的二叉树种类为Catalan数的第n项
对于一棵子树而言,被移动过的节点就是确定的位置。所以仅仅要知道已经确定位置的K个节点有多少个空孩子指针M,和就该子树下的N个未确定位置的节点,等于是说用N个节点构造M个可为空的子树的种类数。对于整个树的形态数即为若干棵独立的子树形态数的乘积。
定义dp[i][j]为用i个节点构造j棵树的形态数。dp[i][j] = sum{ dp[i-1][j-k] * catalan[k] | 0 ≤ k ≤j }, 用o(n^3)的复杂度预处理出dp数组。然后模拟操作后计算出每一个子树的M和N。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 505;
const int mod = 1e9 + 7;
int dp[maxn][maxn], catalan[maxn];
void preserve () {
catalan[0] = catalan[1] = 1;
for (int i = 2; i <= 500; i++) {
for (int j = 0; j < i; j++)
catalan[i] = (catalan[i] + (ll) catalan[j] * catalan[i-j-1]) % mod;
}
dp[0][0] = 1;
for (int i = 1; i <= 500; i++) {
for (int j = 0; j <= 500; j++) {
for (int k = 0; k <= j; k++)
dp[i][j] = (dp[i][j] + (ll) dp[i-1][j-k] * catalan[k]) % mod;
}
}
}
int N, M, far[maxn], son[maxn][2], idx[maxn], cnt[maxn], sum[maxn];
inline int newNode (int f) {
M++;
cnt[M] = son[M][0] = son[M][1] = 0;
far[M] = f;
return M;
}
void init () {
M = 0;
int u = newNode(1), t, k;
idx[u] = M;
for (int i = 1; i <= N; i++) {
scanf("%d", &t);
if (t == 0)
u = far[u];
else if (t <= 2) {
if (son[u][t-1] == 0) {
son[u][t-1] = newNode(u);
idx[son[u][t-1]] = idx[u];
cnt[idx[u]]--;
}
u = son[u][t-1];
} else {
scanf("%d", &k);
son[u][t-3] = newNode(u);
cnt[son[u][t-3]] = k - 1;
idx[son[u][t-3]] = son[u][t-3];
}
}
memset(sum, 0, sizeof(sum));
for (int i = 1; i <= M; i++) {
if (son[i][0] == 0)
sum[idx[i]]++;
if (son[i][1] == 0)
sum[idx[i]]++;
}
}
int solve () {
int ret = 1;
for (int i = 1; i <= M; i++) {
if (idx[i] != i)
continue;
ret = (ll) ret * dp[sum[i]][cnt[i]] % mod;
}
return ret;
}
int main () {
preserve();
int cas = 1;
while (scanf("%d", &N) == 1) {
init ();
printf("Case #%d: %d\n", cas++, solve ());
}
return 0;
}
版权声明:本文为博主原创文章,未经博主同意不得转载。
举报
- 本文已收录于下面专栏:
相关文章推荐
-
hdu-1267 下沙的沙子有几粒 DP/Catalan
题目链接:hdu 5370 Tree Maker n个节点的二叉树种类为Catalan数的第n项 对于一棵子树而言。被移动过的节点就是确定的位置。所以仅仅要知道已经确定位置的K个节点有多少个...- hss871838309
- 2012-03-01 15:06
- 501
-
hdu 4359 Easy Tree DP?
Best solutions forProblem 4359 <div align="right" style="font-family: Arial; font-size: 12px; f- java-mans
- 2012-08-10 14:09
- 370
-
HDU-4714 Tree2cycle(树型dp)
题目链接:hdu 5370 Tree Maker n个节点的二叉树种类为Catalan数的第n项 对于一棵子树而言。被移动过的节点就是确定的位置,所以仅仅要知道已经确定位置的K个节点有多少个...- qq_31759205
- 昨天 00:20
- 11
-
hdu 1023 Train Problem II catalan数列 大数乘除
Train Problem II Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2714Accepted Submission(s): 1517</str- hulunberbus
- 2012-02-28 17:44
- 385
-
HDU5370 Tree Maker
题目链接:hdu 5370 Tree Maker n个节点的二叉树种类为Catalan数的第n项 对于一棵子树而言,被移动过的节点就是确定的位置,所以仅仅要知道已经确定位置的K个节点有多少个...- kyleyoung_ymj
- 2016-06-28 15:52
- 184
-
poj 2378 Tree Cutting(树形dp)
本文出自 <a target="_blank" href="http://blog.csdn.net/shuangde800" style="color: rgb(202,0,0);- king_tt
- 2013-08-31 14:31
- 386
-
2017多校第3场 HDU 6065 RXD, tree and sequence LCA,DP
题目链接:hdu 5370 Tree Maker n个节点的二叉树种类为Catalan数的第n项 对于一棵子树而言,被移动过的节点就是确定的位置,所以仅仅要知道已经确定位置的K个节点有多少个...- just_sort
- 5天前 09:08
- 35
-
ural 1018 Binary Apple Tree(树形dp | 经典)
本文- king_tt
- 2013-09-02 00:49
- 325
-
hdu-1267 下沙的沙子有几粒 DP/Catalan
纠结 的题啊 ACMStep的2.3.8 在2.3里一看题就往Catalan数上想了 非常欣喜的推导出了公式:C[m][n]=(m-n+1)/n*C[m][n-1];C[m][0]=1;当中。m是D能够放置的位置数。最后用大数的处理方式计算出了结果 提交后WA嗄 愣是想了半天不知道为何嗄 最后的最后 找了himdd的博文,发现能够用DP的思想。 解法一:DP 代码及解析例如以下: #include<iost
- java-mans
- 2012-03-01 15:06
- 423
-
HDU 6035 Colorful Tree(树形dp)
题目链接:hdu 5370 Tree Maker n个节点的二叉树种类为Catalan数的第n项 对于一棵子树而言,被移动过的节点就是确定的位置,所以仅仅要知道已经确定位置的K个节点有多少个...- addkai
- 2017-07-29 18:11
- 20
-
原创
- 304
-
粉丝
- 12
-
喜欢
- 0
0条评论