UVA_10247
我们不妨先对k叉树由n-1层变成n层时这一情况讨论一下,看看是否能得到一个递推式。
不妨设f[i]表示k叉树n层时的方案种数,设g[i]为k叉树i层时顶点的个数,首先变成n层时,根节点必须填最小的数,根节点的子节点呢?由于标签都是不同的,那么每棵子树都可以从剩下的标签中选出g[n-1]个标签即可。这样我们就得到了递推式f[n]=multiply{C(i*g[n-1],g[n-1])*f[n-1]}(1<=i<=k)。
于是这样我们就可以先把所有结果预处理出来了。
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner cin = new Scanner(System.in);
BigInteger[][] f = new BigInteger[30][30];
int[][] g = new int[30][30];
for(int i = 1; i <= 21; i ++)
{
f[i][0] = new BigInteger("1");
g[i][0] = 1;
for(int j = 1; i * j <= 21; j ++)
{
f[i][j] = new BigInteger("1");
g[i][j] = i * g[i][j - 1];
g[i][j] ++;
for(int k = i; k >= 1; k --)
f[i][j] = f[i][j].multiply(f[i][j - 1].multiply(C(k * g[i][j - 1], g[i][j - 1])));
}
}
while(cin.hasNext())
{
int k = cin.nextInt();
int d = cin.nextInt();
System.out.println(f[k][d]);
}
}
public static BigInteger C(int m, int n)
{
if(m - n < n)
n = m - n;
BigInteger res = new BigInteger("1");
for(int i = 1; i <= n; i ++)
res = res.multiply(BigInteger.valueOf(m - i + 1)).divide(BigInteger.valueOf(i));
return res;
}
}