zoukankan      html  css  js  c++  java
  • LOJ#6495. 「雅礼集训 2018 Day1」树 题解

    题目链接

    这个题训练的时候做了,结果只有两个人过,而且还有一个写的是状压DP……

    (dp_{n,d}) 表示n个点,最大深度为d的二叉树个数.

    转移分为两种情况:

    1、1号节点只有1个子树。此时的DP值为 (dp_{n-1,d-1}.)

    2、1号节点有多于一个子树。由于2号节点的父亲一定是1,我们考虑枚举2号节点所在子树的大小和最大深度然后暴力转移,复杂度 (Theta(N^4).)

    精细实现应该可以做到 (Theta(N^3).)

    至于求答案下取整的问题,可以考虑使用long double__int128.

    代码 :

    #include <bits/stdc++.h>
    #define LL __int128
    using namespace std;
    inline void print(LL x){
    	if (x > 9) print(x/10); putchar(x%10+'0');
    }
    inline int power(int x,int y,int P){
    	static int r; r = 1;
    	while (y){ if (y&1) r = 1ll * r * x % P; x = 1ll * x * x % P; y >>= 1; }
    	return r;
    }
    LL C[25][25],dp[25][25];
    int main(){
    	int i,j,k,s,t;
    	for (i = 0; i <= 24; ++i) for (j = 0; j <= i; ++j) C[i][j] = (i==j || !i || !j) ? 1 : (C[i-1][j-1] + C[i-1][j]);
    	dp[1][1] = 1;
    	for (i = 2; i <= 24; ++i)
    	for (j = 1; j <= 24; ++j){
    		dp[i][j] = dp[i-1][j-1];
    		for (s = 1; s <= i-2; ++s){
    			for (t = 1; t <= s && t < j-1; ++t) dp[i][j] += C[i-2][s-1] * dp[s][t] * dp[i-s][j];
    			LL tot = 0;
    			for (k = 1; k <= j; ++k) tot += dp[i-s][k];
    			dp[i][j] += C[i-2][s-1] * dp[s][j-1] * tot;
    		}
    	}
    	int P,n; cin >> n >> P;
    	LL sumd = 0,frac = 1;
    	for (i = 1; i <= n; ++i) sumd += i * dp[n][i];
    	for (i = 1; i < n; ++i) frac *= i;
    	print((sumd * 2 + frac) / frac / 2),putchar('
    ');
    	sumd = sumd % P * power(frac % P,P-2,P) % P;
    	print(sumd),putchar('
    ');
    	return 0;
    }
    
  • 相关阅读:
    这些年学过的FPGA
    基于SoCkit的opencl实验1-基础例程
    基于8051内核的实验—流水灯
    8051内核的使用
    基于FPGA的电压表与串口通信(下)
    基于FPGA的电压表与串口通信(上)
    基于FPGA的通信信号源的设计
    基于DDS的任意波形发生器
    基于FPGA的通信系统实验
    进程间通信三(共享内存)
  • 原文地址:https://www.cnblogs.com/s-r-f/p/13599396.html
Copyright © 2011-2022 走看看