Cow Pedigrees
- The degree of each node is 0 or 2. The degree is the count of the node's immediate children.
- The height of the tree is equal to K (1 < K <100). The height is the number of nodes on the longest path from the root to any leaf; a leaf is a node with no children.
How many different possible pedigree structures are there? A pedigree is different if its tree structure differs from that of another pedigree. Output the remainder when the total number of different possible pedigrees is divided by 9901.
PROGRAM NAME: nocows
INPUT FORMAT
- Line 1: Two space-separated integers, N and K.
SAMPLE INPUT (file nocows.in)
5 3
OUTPUT FORMAT
- Line 1: One single integer number representing the number of possible pedigrees MODULO 9901.
SAMPLE OUTPUT (file nocows.out)
2
OUTPUT DETAILS
Two possible pedigrees have 5 nodes and height equal to 3:@ @ / \ / \ @ @ and @ @ / \ / \ @ @ @ @
这道题一开始找了半天也没有找到子结构,不知道是脑子秀逗了还是什么
一直在把单独的一个节点插来插去在那边看,完全没有考虑整体的插入
按Analysis上的说法是,f[i][j]为高为i,节点数为j时的可能情况数
但是这样还需要额外统计高<=i的各个情况
干脆我们不管,统计高<=i的情况,然后f[i][j]-f[i-1][j]就是答案
两个代码如下:
/*
ID: conicoc1
LANG: C
TASK: nocows
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAXHIGH 101
#define MAXROOT 201
#define MOD 9901
int CowTree[MAXHIGH][MAXROOT]; //高度,节点数
int TreeHigh,TreeRoot;
int SmallTree[MAXHIGH][MAXROOT]; //高度小于MAXHIGH,节点数为root的情况
int main()
{
FILE *fin,*fout;
fin=fopen("nocows.in","r");
fout=fopen("nocows.out","w");
memset(CowTree,0,sizeof(CowTree));
memset(SmallTree,0,sizeof(SmallTree));
fscanf(fin,"%d %d",&TreeRoot,&TreeHigh);
int i,j,k;
CowTree[1][1]=1; //初始化高为1,节点数为1的情况
for(i=2;i<=TreeHigh;i++)
{
for(j=1;j<i-1;j++)
{
for(k=2*j-1;k<=TreeRoot;k+=2)
{
SmallTree[i-1][k]=(SmallTree[i-1][k]+CowTree[j][k])%MOD; //高度小于i-1,节点数为k的情况
}
}
for(j=2*i-1;j<=TreeRoot;j+=2)
{
for(k=1;k<=j-2;k+=2)
{
CowTree[i][j]=(CowTree[i][j]+CowTree[i-1][k]*CowTree[i-1][j-k-1])%MOD;
CowTree[i][j]=(CowTree[i][j]+CowTree[i-1][k]*SmallTree[i-1][j-k-1]*2)%MOD;
}
}
}
fprintf(fout,"%d\n",CowTree[TreeHigh][TreeRoot]);
return 0;
}
/*
ID: conicoc1
LANG: C
TASK: nocows
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#define MAXHIGH 101
#define MAXROOT 201
#define MOD 9901
int CowTree[MAXHIGH][MAXROOT]; //表示高度<=MAXHIGH,节点数为MAXROOT的情况数
int TreeRoot,TreeHigh;
int Answer;
int main()
{
FILE *fin,*fout;
fin=fopen("nocows.in","r");
fout=fopen("nocows.out","w");
memset(CowTree,0,sizeof(CowTree));
fscanf(fin,"%d %d",&TreeRoot,&TreeHigh);
int i,j,k;
for(i=1;i<=TreeHigh;i++)
CowTree[i][1]=1;
for(i=1;i<=TreeHigh;i++)
for(j=1;j<=TreeRoot;j+=2)
for(k=1;k<=j-2;k+=2)
CowTree[i][j]=(CowTree[i][j]+CowTree[i-1][k]*CowTree[i-1][j-k-1])%MOD;
fprintf(fout,"%d\n",(CowTree[TreeHigh][TreeRoot]-CowTree[TreeHigh-1][TreeRoot]+MOD)%MOD);
return 0;
}
第二种最后输出答案的时候想当然了,因为考虑到最后一减可能为负的情况,我居然直接用abs取绝对值。。。显然对于模运算这是要出事情的。。。
我感觉我对于DP的题目一点感觉都没有,好僵硬。。。