博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 5629 Clarke and tree dp+prufer序列
阅读量:5142 次
发布时间:2019-06-13

本文共 1110 字,大约阅读时间需要 3 分钟。

题意:有中文题面 bc round 72 div1 d

分析:首先需要知道一棵无根树对应的prufer序列,如果没学过,可以看百度百科

http://baike.baidu.com/link?url=R6v5kao_NQejPfQq3A2yyAa6itaeUOrIxYwEEraSy7b2ifFJsM8CSJ6ve7BtHe2G5CakJThZ-3IMFd37zmvcQK

然后,补充一点关于prufer序列的知识

一个prufer序列唯一对应一个树,一个n个点树,对应一个长度为n-2的prufer序列

然后可以发现一个节点在prufer数列中出现的次数是这个节点的度数减一。

这样我们就知道这个数列中有哪些数了,以及这些节点出现的次数

然后问题就变成了求有多少种prufer数列,一个数列对应一个树

又因为我们知道了元素种类与出现次数。于是问题就变成了求一个有重复元素的全排列。

所以对于求节点个数为n 的树的个数,就是求排列数

然后进行dp吧

dp[i][j][k]

表示决策到第i个点,树上的点选了j个了,目前总出现次数是k的方案数

然后更新就更新看代码吧

 

#include 
#include
#include
using namespace std;typedef long long LL;const int N = 55;const LL mod = 1e9+7;LL dp[N][N][N],c[N][N];int a[N];int main(){ c[0][0]=1; for(int i=1;i<=50;++i) { c[i][0]=1; for(int j=1;j<=50;++j) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mod; } int T,n; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;++i) scanf("%d",&a[i]); memset(dp,0,sizeof(dp)); dp[0][0][0]=1; for(int i=0;i
View Code

 

转载于:https://www.cnblogs.com/shuguangzw/p/5217139.html

你可能感兴趣的文章
AHK Listview排序函数
查看>>
文件的暂存(git add)
查看>>
时间即效率,从高效办公到中华上下五千年
查看>>
新开始
查看>>
ccp4 functions
查看>>
[SQL Server] Excel文件导入SQL Server数据库表
查看>>
Windows10实用技巧-固定快捷方式到磁贴菜单方式
查看>>
mime.go
查看>>
微信公众平台接口配置问题
查看>>
SQL查询记录添加序号(HANA)
查看>>
Java中Split函数的用法技巧
查看>>
JAVA NIO 笔记(2)
查看>>
Redis批量导入数据的方法
查看>>
微信公众号、人脉拓展、运营
查看>>
Visual Studio 2010 单元测试
查看>>
mysql delete语句不能用别名
查看>>
ZOJ2760 How many shortest path(网络流)
查看>>
MySQL恢复root用户超级权限方法
查看>>
正则表达式
查看>>
canvas svg webgl threejs d3js 的区别
查看>>