ACdream 1412 DP+排列组合

2-3 Trees

Problem Description

      2-3 tree is an elegant data structure invented by John Hopcroft. It is designed to implement the same functionality as the binary search tree. 2-3 tree is an ordered rooted tree with the following properties:

  • the root and each internal vertex have either 2 or 3 children;
  • the distance from the root to any leaf of the tree is the same.

      The only exception is the tree that contains exactly one vertex — in this case the root of the tree is the only vertex, and it is simultaneously a leaf, i.e. has no children. The main idea of the described properties is that the tree with l leaves has the height O(log l).
      Given the number of leaves l there can be several valid 2-3 trees that have l leaves. For example, the picture below shows the two possible 2-3 trees with exactly 6 leaves.


      Given l find the number of different 2-3 trees that have l leaves. Since this number can be quite large, output it modulo r.

Input

      Input file contains two integer numbers: l and r (1 ≤ l ≤ 5 000, 1 ≤ r ≤ 109).

Output

      Output one number — the number of different 2-3 trees with exactly l leaves modulo r.

Sample Input

6 1000000000
7 1000000000

Sample Output

2
3

Source

Andrew Stankevich Contest 21
 
题意:
  2-3树定义为,每个非叶子节点都有2个或者是3个儿子;根节点到每个叶子的距离都相等
  问你对于给定的n个叶子节点其树不同形态有多少种
题解:
  DP[i] 表示叶子节点数为i的树的方案,枚举2,3儿子的节点的数量,得到下一层,注意了,23排列不同造成形态不同,这个要排列组合计算
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
const int N=4e5+110,mods=20090717,inf=2e9+10;

int n,mod,c[3001][3001];
LL dp[N];
int main() {
    while(scanf("%d%d",&n,&mod)!=EOF) {
    for(int i = 0; i <= 3000; ++i) {
        c[i][0] = 1;
        for(int j = 1; j <= i; ++j) {
            c[i][j] = (c[i-1][j] + c[i-1][j-1])%mod;
        }
    }
        memset(dp,0,sizeof(dp));
        dp[1] = 1;
        for(int i = 1; i <= n; ++i) {
            for(int j = 0; j <= i; ++j) {
                if(j*2 + (i-j)*3 <= 5000)
                dp[j*2 + (i-j)*3] += dp[i]*c[i][j],
                dp[j*2 + (i-j)*3]%=mod;
            }
        }
        printf("%lld\n",dp[n]%mod);
    }
    return 0;
}

 

posted @ 2017-03-13 20:59  meekyan  阅读(179)  评论(0编辑  收藏  举报