[jzoj]3874. 【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)(树形DP+组合数)
来源:互联网 发布:正当防卫3内存优化补丁 编辑:程序博客网 时间:2024/06/06 08:26
Problem
求n个节点满足以下性质的不同的树有多少种。
1、树是有标号的,每个节点被标上1到n之间的整数;
2、每个节点最多和其他3个节点相连,但是1号节点最多和其他2个节点相连;
3、这棵树的最大匹配(把树看成二分图后的最大匹配)数为k。
两棵树被认为不同当且仅当存在两个点u、v,在一棵树中u、v之间有边,另一棵树中u、v之间没边。
输出方案数 mod 1e9+7
Data Constraint
对于30%的数据,2≤n≤5;
对于60%的数据,2≤n≤20;
对于100%的数据,2≤n≤50。
Solution
我们设
f[i][j][0/1] 表示当前由i 个节点组成的一棵树,最大匹配为j ,根节点是否选择.我们知道,根节点是否选择,所影响的最大匹配不会超过1,且选根节点,一定比不选优.
那么因为此题的一个重要性质是:
- 该树是二叉树
所以我们可以考虑经典的二叉树DP方法:
枚举整棵树的大小及左子树的大小,从而推出右子树的大小,转移.
设左子树的状态为
f[x][T1][0/1] ,右子树即为f[y][T2][0/1] ,满足x+y=n−1 那么我们可以通过“根节点是否选择,所影响的最大匹配不会超过1”来得出
f[i][S][0/1] 中的S .并进行转移,转移的时候需要注意的是“顺序”.
因为这
n 个节点组成的树,树的节点是有顺序的,所以我们要乘上一个左子树的方案数(C(i−1,x) 种),以及根有多少种可能(i 种)但需要注意一点就是,当
x=y 时,我们任意的一种方案,左子树和右子树都会相同,所以我们要除以2 .具体实现看标
#include <iostream>#include <cstdio>#include <cstring>#define ll long longconst ll Maxn = 100, mo = 1e9 + 7;using namespace std;ll n,k,x[Maxn],y[Maxn],pre[Maxn],jc[Maxn],ny[Maxn],ans;ll f[Maxn][50][2];ll C(ll x,ll y){ return ((jc[x] * ny[y] % mo) * ny[x-y]) % mo;}ll ksm(ll x,ll y){ ll sum = 1; while (y) { if (y & 1) sum = (sum * x) % mo; x = (x * x) % mo; y = y / 2; } return sum;}int main(){ scanf("%lld%lld",&n,&k), jc[0] = ny[0] = 1; for (ll i=1;i<=n;i++) jc[i] = (jc[i-1] * i) % mo, ny[i] = ksm(jc[i],mo-2); f[0][0][0] = f[1][0][0] = 1; for (ll i = 2; i <= n; i++) { for (ll x = i / 2; x < i; x++) { ll y = i - x - 1, maxer1 = x / 2, maxer2 = y / 2, s1 = (C(i-1,x) * i) % mo, s2; if (x==y) s2 = ksm(2,mo-2); else s2 = 1; for (ll T1 = 0; T1 <= maxer1; T1++) { if (f[x][T1][0]+f[x][T1][1]==0) continue; if (y == 0) { f[i][T1+1][1] = (f[i][T1+1][1] + (i * f[x][T1][0]) % mo ); f[i][T1] [0] = (f[i][T1] [0] + (i * f[x][T1][1]) % mo ); continue; } for (ll T2 = 0; T2 <= maxer2; T2++) { if (f[y][T2][0]+f[y][T2][1]==0) continue; f[i][T1+T2+1][1] = (f[i][T1+T2+1][1] + (((f[x][T1][0] * f[y][T2][1]) % mo) * ((s1 * s2) % mo) )); f[i][T1+T2+1][1] = (f[i][T1+T2+1][1] + (((f[x][T1][1] * f[y][T2][0]) % mo) * ((s1 * s2) % mo) )); f[i][T1+T2+1][1] = (f[i][T1+T2+1][1] + (((f[x][T1][0] * f[y][T2][0]) % mo) * ((s1 * s2) % mo) )) % mo; f[i][T1+T2] [0] = (f[i][T1+T2 ][0] + (((f[x][T1][1] * f[y][T2][1]) % mo) * ((s1 * s2) % mo) )) % mo; } } } } printf("%lld",((f[n][k][0] + f[n][k][1]) * (ksm(n,mo-2))) % mo);}
遇到这种类型的题目,要求构出一颗二叉树的,满足什么条件,一般都分左子树,和右子树来转移
一定要注意组合数.
阅读全文
0 0
- [jzoj]3874. 【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)(树形DP+组合数)
- 【JZOJ3874】【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)
- 高中OJ3874. 【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)
- 【NOIP2014八校联考第4场第2试10.20】准备复赛
- JZOJ 3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- jzoj. 3873. 【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- jzoj 3850. 【NOIP2014八校联考第2场第1试9.27】Fibonacci进制(fib) 数位dp
- JZOJ 3852. 【NOIP2014八校联考第2场第2试9.28】单词接龙(words)
- JZOJ 3853. 【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help)
- JZOJ 3870. 【NOIP2014八校联考第4场第1试10.19】单词检索(search)
- [JZOJ]3858. 【NOIP2014八校联考第3场第2试10.5】挖掘机技术哪家强
- [JZOJ]3859. 【NOIP2014八校联考第3场第2试10.5】孤独一生
- 【NOIP2014八校联考第1场第1试9.20】统计损失(count)(树形dp)
- [jzoj]3875. 【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)(图论题,构树+缩点+LCA+并查集)
- 【JZOJ 3853】【NOIP2014八校联考第2场第2试9.28】帮助Bsny(help) (详解)
- 【JZOJ3873】【NOIP2014八校联考第4场第2试10.20】乐曲创作(music)
- 【JZOJ3875】【NOIP2014八校联考第4场第2试10.20】星球联盟(alliance)
- 【NOIP2014八校联考第4场第2试10.20】乐曲创作
- android material doc
- 翻译:MariaDB ALTER TABLE语句
- java打地鼠游戏
- 为什么你需要将代码迁移到ASP.NET Core 2.0?
- 错误——MySQL在navicat打开时出现1045
- [jzoj]3874. 【NOIP2014八校联考第4场第2试10.20】准备复赛(exam)(树形DP+组合数)
- windows anaconda3 tensorflow作为Keras的backend
- PowerBI开发 第六章:数据网管
- java 文件大小格式化显示工具
- 蓄水池算法
- python 2和python 3相互切换
- 【知识整理】Node.js-Sequelize之原始查询
- gym101102I(模拟)
- Java 网络 IO 模型