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;
    }
    
  • 相关阅读:
    C++11 特色语法在 OI 中的运用
    webpack基本使用(一)
    LeetCode 887. 鸡蛋掉落 题解
    Codeforces Round #735 (Div. 2) C. Mikasa
    阿里云RDS与ECS自建mysql数据库主从同步(GTID方式)
    MySQL 5.7.x修改root默认密码
    SpringBoot引入第三方jar包或本地jar包的处理方式
    K8s 常用命令(随时更新......)
    六 Prometheus + Altermanager Email 报警
    四 Prometheus + consul
  • 原文地址:https://www.cnblogs.com/youth518/p/13823539.html
Copyright © 2011-2022 走看看