您的位置:首页 > 其它

UVALive 4847 Binary Search Tree【树型dp】

2012-10-19 21:16 399 查看
题目大意:给定一个1-n的排列,依次将这些数插入到二叉排序树中,问总共有多少个排列使得构成的二叉树和给定的排列构成的二叉树相同

本题的思路就是:先构成要求的二叉排序树,然后再在树上进行dp

状态转移为:dp[rt] = dp[lson]*dp[rson]*c(lson,sum);

lson 表示左子树的点的个数,sum表示左右子树点的个数之和。

c(a,b) 表示b中过选择a个的组合数。状态转移应该是比较好理解的吧 

代码写的比较挫,毕竟不常写二叉树

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
#define mod 9999991
struct note
{
int val,l,r,size;
long long dp;
}dat[100];
int kk;
void init()
{
for(int i = 0;i < 100;i++)
{
dat[i].l = dat[i].r = -1;
dat[i].val = 0;
dat[i].dp = 1;
dat[i].size = 1;
}
}
void insert(int rt,int val)
{
if(val < dat[rt].val)
{
if(dat[rt].l == -1)
{
dat[rt].l = kk;
dat[kk].val = val;
kk++;
return;
}else insert(dat[rt].l,val);
}else
{
if(dat[rt].r == -1)
{
dat[rt].r = kk;
dat[kk].val = val;
kk++;
return;
}else insert(dat[rt].r,val);
}
}
long long c[100][100];
void C()
{
int i,j;
c[0][0]=1;
for(i=1;i<40;i++) //自定义
for(j=0;j<=i;j++)
c[i][j]=(j==0)?c[i-1][j]:c[i-1][j]+c[i-1][j-1]; //公式
}
void dfs(int rt)
{
if(dat[rt].l == -1 && dat[rt].r == -1)
{
return;
}
if(dat[rt].l != -1) dfs(dat[rt].l);
if(dat[rt].r != -1) dfs(dat[rt].r);
if(dat[rt].l != -1 && dat[rt].r != -1)
{
dat[rt].size = dat[dat[rt].l].size + dat[dat[rt].r].size + 1;
int cc = c[ dat[rt].size-1 ][ dat[dat[rt].l].size ];
dat[rt].dp = cc*dat[dat[rt].l].dp * dat[dat[rt].r].dp%mod;
}else if(dat[rt].l == -1)
{
dat[rt].size = dat[ dat[rt].r ].size+1;
dat[rt].dp = dat[dat[rt].r].dp;
}else
{
dat[rt].size = dat[ dat[rt].l ].size+1;
dat[rt].dp = dat[dat[rt].l].dp;
}
}
int main()
{
C();
//cout << c[20][10];
int t;
cin >> t;
while(t--)
{
init();
int n;
cin >> n;
int tt;
kk = 2;
for(int i = 0;i < n;i++)
{
cin >> tt;
if(i == 0) dat[1].val = tt;
else insert(1,tt);
}

dfs(1);
cout << dat[1].dp << "\n";
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  search tree insert c struct