USACO 2.3.2 Cow Pedigrees题解

【算法】动态规划  【难度】★★★☆☆  


一看就是DP,但是很可惜我完全没有思路= =

看了题解,nocow上讲的很透彻,两种方法都很好。

首先明确一下题目的意思:用N个点组成一棵深度为K的二叉树,求一共有几种方法? 设dp[i,j]表示用i个点组成深度最多为j的二叉树的方法数,则:
dp[i,j]=∑(dp[k,j-1]×dp[i-1-k,j-1])(k∈{1..i-2})  初始化:dp[1,i]=1
我们要求的是深度恰好为K的方法数S,易知S=dp[n,k]-dp[n,k-1]。 但需要注意的是,如果每次都取模,最后可能会有dp[n,k]<dp[n,k-1],所以可以用S=(dp[n,k]-dp[n,k-1]+v) mod v

以上引自nocow。另一种方法也很好,但这种更好理解一些。

【收获】动规的思路值得借鉴

View Code
/*
ID: wsc5001
LANG: C
TASK: nocows
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int dp[202][102];
int n,k;
int main()
{
freopen("nocows.in","r",stdin);
freopen("nocows.out","w",stdout);
scanf("%d%d",&n,&k);
int i,j,e;
for (i=1;i<=k;i++)
dp[1][i]=1;
for (i=2;i<=n;i++)
for (j=1;j<=k;j++)
for (e=1;e<=i-2;e++)
{
dp[i][j]+=dp[e][j-1]*dp[i-1-e][j-1];
dp[i][j]%=9901;
}
printf("%d\n",(dp[n][k]-dp[n][k-1]+9901)%9901);
//system("pause");
fclose(stdin);

fclose(stdout);
}



posted @ 2012-03-25 19:16  wsc500  阅读(284)  评论(0编辑  收藏  举报