zoukankan      html  css  js  c++  java
  • P2767 树的数量 DP | 组合数学

    题面:

    给定(n,m)(n)个节点的(m)叉树的形态有多少种

    范围&性质:(1le n,mle 127)

    分析:

    • DP做法

    (m)等于2时就是卡特兰数,详情见卡特兰数定义和递推式

    那我们考虑像Catlan数一样枚举每个儿子的大小然后组合起来,所以设(f[i][j])表示表示根节点有(i)(m)叉子树,总个数为(j)的方案数,(g[i])表示用(i)个点构成一颗(m)叉树的方案数,转移时相当于往根节点上接一颗(m)叉树

    [f[i][j]=sum g[k] imes f[i-1][j-k] ]

    为了消掉转移对原有状态的影响,还应该更新(g)数组

    [g[i]=f[m][i] ]

    复杂度(O(n^3))

    • 组合做法

    我们将每个节点有几个儿子记录下来,按照编号会组成一个序列,序列里的每一项值的大小不会超过(m),序列一共有(n)项,每一个合法的序列一定满足元素之和等于(n-1),也就是说它的组合意义就是从(n*m)个点中选出(n-1)个的合法方案数,我们发现按照(dfs)序选儿子,每次能选的点会变少(因为已经被选过的点是不能选的)

    所以对于所有情况合法的方案占总方案数的(prod_{i=1}^{n-1} frac{i}{i+1}=frac{1}{n})

    最后总的答案就是(ans=frac{C(n*m,n-1)}{n})

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	const int mod = 10007;
    	long long n,m;
    	long long fac[mod+5],inv[mod+5];
    	
    	void init()
    	{
    		fac[0]=fac[1]=1;
    		inv[0]=inv[1]=1;
    		for(int i=2;i<=mod;i++)
    		{
    			fac[i]=fac[i-1]*i%mod;
    			inv[i]=inv[mod%i]*(mod-mod/i)%mod;
    		}
    		for(int i=2;i<=mod;i++) inv[i]=inv[i]*inv[i-1]%mod;
    	}
    	
    	long long qpow(long long x,long long y)
    	{
    		long long res=1;
    		while(y)
    		{
    			if(y&1) res=res*x%mod;
    			x=x*x%mod;
    			y>>=1;
    		}
    		return res;
    	}
    	
    	long long C(long long n,long long m)
    	{
    		if(m>n) return 0;
    		return fac[n]*inv[n-m]%mod*inv[m]%mod;
    	}
    	
    	long long lucas(long long n,long long m)
    	{
    		if(!m) return 1;
    		return lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod;
    	}
    	
    	void work()
    	{
    		init();
    		scanf("%lld%lld",&n,&m);
    		printf("%lld
    ",lucas(n*m,n-1)*qpow(n,mod-2)%mod);
    	}
    
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
  • 相关阅读:
    tp3中子查询 逻辑条件是or
    数据量大的情况用布隆过滤器判断是否已存在
    pip 通过pqi切换源到国内镜像
    php先响应后处理
    selenium登录网银,密码控件输入
    mysql 查询a表在b表中不存在的记录
    下列java代码中的变量a、b、c分别在内存的______存储区存放。
    关于选中的磁盘具有MBR分区表。在EFI系统上,Windows只能安装到GPT磁盘。问题解决
    VBOX不能为虚拟电脑打开一个新任务解决方法
    解决虚拟机似乎正在使用的问题
  • 原文地址:https://www.cnblogs.com/youth518/p/13823539.html
Copyright © 2011-2022 走看看