Easy Tree DP?
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 174 Accepted Submission(s): 65
Problem Description
A Bear tree is a binary tree with such properties : each node has a value of 2
0,2
1…2
(N-1)(each number used only once),and for each node ,its left subtree’s elements’ sum<its right subtree’s elements’ sum(if the node hasn’t left/right subtree ,this limitation is invalid).
You need to calculate how many Bear trees with N nodes and exactly D deeps.
You need to calculate how many Bear trees with N nodes and exactly D deeps.
Input
First a integer T(T<=5000),then T lines follow ,every line has two positive integer N,D.(1<=D<=N<=360).
Output
For each test case, print "Case #t:" first, in which t is the number of the test case starting from 1 and the number of Bear tree.(mod 10
9+7)
/*
* =====================================================================================
*
* Filename: P1010.cpp
*
* Description:
*
* Version: 1.0
* Created: 2012年08月09日 14时07分27秒
* Revision: none
* Compiler: gcc
*
* Author: Mad13 (),
* Organization:
*
* =====================================================================================
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <algorithm>
#define Mid(a) ((a)>>1)
#define R(a) (((a)<<1)+1)
#define L(a) ((a)<<1)
#define maxn 400
#define clear(a,b) memset(a,b,sizeof(a))
#define MOD 1000000007
#define LL long long
int Max(int a,int b)
{
if (a > b) return a;
return b;
}
int Min(int a,int b)
{
if (a > b) return b;
return a;
}
LL dp[maxn+10][maxn+10],sum[maxn+10][maxn+10],C[maxn+10][maxn+10];
int cas;
int init()
{
clear(dp,0);
clear(sum,0);
clear(C,0);
int i,j,rest,k,d;
C[0][0] = 1; //cal C
for(i = 1;i <= maxn;i++){
C[i][0] = 1;
for(j = 1;j <= i;j++) C[i][j] = (C[i-1][j] + C[i-1][j-1]) % MOD;
}
for(i = 1;i <= maxn;i++) { //
sum[1][i] = 1;
}
dp[1][1] = 1;
for(i = 2;i <= maxn;i++) {
for(j = 2;j <= i;j++) {
dp[i][j] += (2 * i * dp[i-1][j-1]) % MOD;
for(k = 1;k <= i-2;k++) {
rest = i - k - 1;
dp[i][j] += (((i * C[i-2][k]) % MOD) * (
(sum[k][j-1]*dp[rest][j-1])%MOD
+ (sum[rest][j-1]*dp[k][j-1])%MOD
- (dp[k][j-1]*dp[rest][j-1])%MOD ) % MOD) % MOD;
dp[i][j] = ((dp[i][j]) % MOD + MOD) % MOD;
}
sum[i][j] = (sum[i][j-1] + dp[i][j]) % MOD;
}
for(d = i+1;d <= maxn;d++) sum[i][d] = sum[i][d-1];
}
return 0;
}
int work()
{
int n,d;
scanf("%d%d",&n,&d);
printf("Case #%d: %lld\n",cas,dp[n][d]);
return 0;
}
int main()
{
int t;
init();
scanf("%d",&t);
for(cas = 1;cas <= t;cas++) work();
return 0;
}