题意:求K层N节点的二叉树一共有种
解题思路:
- 读入N和K
- DP问题,参考NOCOW解题思路(http://www.nocow.cn/index.php/USACO/nocows)
- 关键步骤略有不同,如下
-
for (i=2; i<=K; i++) { for (j=1; j<=N; j+=2) { for (k=1; k<=(j-2); k+=2) { table[i][j] += (2*(smalltrees[i-2][k]*table[i-1][j-1-k]) + table[i-1][k]*table[i-1][j-1-k]); table[i][j] %= 9901; } smalltrees[i][j] = ((smalltrees[i-1][j] + table[i][j]) % 9901); } }
代码:
/*
ID: zc.rene1
LANG: C
PROG: nocows
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
FILE *fin, *fout;
int N, K;
int **table, **smalltrees;
int i, j, k;
fin = fopen("nocows.in", "r");
fout = fopen("nocows.out", "w");
fscanf(fin, "%d %d", &N, &K);
table = (int**)malloc((K+1)*sizeof(int*));
smalltrees = (int**)malloc((K+1)*sizeof(int*));
for (i=0; i<K+1; i++)
{
table[i] = (int*)malloc((N+1)*sizeof(int));
smalltrees[i] = (int*)malloc((N+1)*sizeof(int));
memset(table[i], 0, (N+1)*sizeof(int));
memset(smalltrees[i], 0, (N+1)*sizeof(int));
}
table[1][1] = 1;
smalltrees[1][1] = 1;
for (i=2; i<=K; i++)
{
for (j=1; j<=N; j+=2)
{
for (k=1; k<=(j-2); k+=2)
{
table[i][j] += (2*(smalltrees[i-2][k]*table[i-1][j-1-k]) + table[i-1][k]*table[i-1][j-1-k]);
table[i][j] %= 9901;
}
smalltrees[i][j] = ((smalltrees[i-1][j] + table[i][j]) % 9901);
}
}
fprintf(fout, "%d\n", table[K][N]%9901);
return 0;
}