!HDU 4359 左子树节点和小于右子树的树有多少种-dp

题意:n个节点,每个节点的权值为2^0,2^1....2^(n-1),求满足任何节点的左子树的节点和小于右子树的节点和的分配方案有多少种

分析:

由于等比数列的性质:1+2+....2^(k-1)<2^k,所以除了根节点的权值以外的,最大值必须在右子树,其余节点随意。

情况有:1.只有左子树,2.只有右子树,3.都有

dp[i][j]:表示选i个节点深度<=j的树的分配方案

转移:dp[i][j]+=C(i-2,k)*dp[k][j-1]*dp[i-1-k][j-1],这里用到了组合数性质,或者说杨辉三角性质。

这题的dp还不是很懂。

代码:

#include<iostream>
#include<cstring>
#define INF 1000000007
using namespace std;
long long c[1000][1000],dp[400][400];
int n,h;
void init()
{
	memset(dp,0,sizeof(dp));
	memset(c,0,sizeof(c));
	c[0][0]=1;
	for(int i=1;i<=360;i++){
		c[i][0]=1;
		c[i][i]=1;
		for(int j=1;j<i;j++){
			c[i][j]=(c[i-1][j-1]+c[i-1][j])%INF;
		}
	}
	for(int i=0;i<=360;i++) dp[0][i]=1;
	for(int j=1;j<=360;j++) dp[1][j]=1;
	for(int i=2;i<=360;i++){
		for(int j=1;j<=360;j++){
			dp[i][j]+=dp[i-1][j-1]*2%INF;
			dp[i][j]%=INF;
			for(int k=1;k<=i-2;k++){
				dp[i][j]+=c[i-2][k]*dp[k][j-1]%INF*dp[i-1-k][j-1]%INF;
				dp[i][j]%=INF;
			}
			dp[i][j]*=i;
			dp[i][j]%=INF;
		}
	}
}
int main()
{
	init();
	int t;
	cin>>t;
	for(int cas=1;cas<=t;cas++){
		cin>>n>>h;
		long long ans=((dp[n][h]-dp[n][h-1])%INF+INF)%INF;
	    cout<<"Case #"<<cas<<": "<<ans<<endl;
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 04:47:54

!HDU 4359 左子树节点和小于右子树的树有多少种-dp的相关文章

!HDU 4345 置换群的环长有多少种-dp

题意:置换群,问环的长度有多少种 分析: 环的长度就是每次你选择的区间长度的最小公倍数.总区间长度是n,那么这道题就是求和等于n的各个数的最小公倍数有多少种. 状态:dp[i][j]前i个质数,区间长度不超过j的最优解 转移:dp[i][j]=dp[i-1][j]+dp[i-1][j-k],k=prim[i]^1,2... 这题和上一题的dp难哭我了. 代码: #include<iostream> #include<cstdio> #include<algorithm>

hdu 4359 dp

1 /* 2 题目大意:给n个节点的二叉树第i个节点的权值为2^(i-1), 3 求所有含左右子树的节点都符合左子树的权和小于右子树权和的种数. 4 */ 5 #include <iostream> 6 #include <cstdio> 7 #include <cstring> 8 using namespace std; 9 10 typedef __int64 LL; 11 const int maxn=365; 12 const int mod=1e9+7; 1

HDU 4359 Easy Tree DP?(是dp但并不是tree dp + 组合计数)

HDU 4359 题意:定义Bear Tree为一颗二叉树,这种二叉树每个结点有一个权值,范围在2^0~2^n-1,并且每个值只用一次,对于每个结点,如果同时存在左右子树,那么左子树的权值和要小于右子树的权值和.求点数为N,层次为D的Bear Tree的数量. 思路: 2^0 + 2^1 + ... + 2^n < 2^(n+1) 根据这个性质,我们可以得出权值最大节点必须在右子树上,并且只要同时存在左右子树,则将权值最大节点放在右子树上就一定符合条件. 所以我们用dp[i][j]表示点数为i且

HDU 4359 Easy Tree DP? 组合数学+动归

题意:定义一种树,每个节点的权值都是20到2n-1,每个权值出现一次,每个节点的左子树的权值和小于右子树.给你n和d,问有n个节点且恰好深度是d的这种树有多少种. 比赛的时候我没有做出来,当时A的人还是不少,\ 有一个超傻逼的居然没想到,就是  ,这表示一个权值较大的节点是大于所有权值小于他的值之和的. 所以对于每一个合法的树,只要把权值最大的放到右子树就可以满足了. 动归过程:f[i][j]表示i个节点深度不超过j的方案种数.

HDU 4359——Easy Tree DP?——————【dp+组合计数】

Easy Tree DP? Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1460    Accepted Submission(s): 557 Problem Description A Bear tree is a binary tree with such properties : each node has a value o

15.输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点, 用递归和循环两种方法完成树的镜像转换

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4260432.html  声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:输入一颗二元查找树,将该树转换为它的镜像, 即在转换后的二元查找树中,左子树的结点都大于右子树的结点, 用递归和循环两种方法完成树的镜像转换. 题目分析:

【转】将一棵树转换为二叉树后,为什么根节点没有右子树

树转化为二叉树时结点左子树是原来的孩子结点,右子树是原来的兄弟结点.即取根节点左孩子向右连接他的兄弟结点(在同一层次的节点,原来互不相连)并把它的子树,而把除左孩子外,原来与根节点相连的线擦除.这样根节点没有右孩子,因为由树转化来的二叉树某个节点A的左子树是原来作为树时A的孩子,其右子树是他的兄弟. 原文地址:https://www.cnblogs.com/schips/p/10630811.html

交互二叉树的所有左子树和右子树.

递归实现: 真正对递归的调用过程很熟悉的哥们才很顺,虽然这个题目代码看起来不难,但是我在纸上画出调用过程后,才弄明白是什么个过程. 1 //交换所有二叉树的左子树和右子树. 2 void 3 swap(PNode p) { 4 if(!p) return; 5 6 swap(p->lchild); 7 swap(p->rchild); 8 9 PNode t; 10 t = p->lchild; 11 p->lchild = p->rchild; 12 p->rchil

HDU 4359 Easy Tree DP? 带权二叉树的构造方法 dp

题意: 给定n deep 1.构造一个n个节点的带权树,且最大深度为deep,每个节点最多只能有2个儿子 2.每个节点的值为2^0, 2^1 ··· 2^(n-1)  任意两个节点值不能相同 3.对于一个节点,若他有左右儿子,则左子树的和 < 右子树的和 问: 有多少种构造方法. 思路: dp #include <stdio.h> #include <iostream> #include <algorithm> #include <cstring> u