csuoj 1351: Tree Counting

这是一个动态规划的题;

当初想到要用dp,但是一直想不到状态转移的方程;

题解上的原话:

  动态规划,设 g[i]表示总结点数为 i 的方案种数,另设 f[i][j]表示各个孩子的总结点数为
i,孩子的个数为 j 的方案数,那么有 g[i+1]=f[i][1]+f[i][2]+...+f[i][k],相当于添加一个根节
点之后变成完整的树,同时要把有 1 个孩子,2个孩子, ……,k 个孩子的情况都考虑进去。
对于 f[i][j]的求解可以用类似背包的方法去做,在求解的时候也会用到 g[1], g[2], ..., g[i]
的值,根据前面的那个 g[i+1]的表达式来看,这些 g[]已经在前面算出来了。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 205
#define mod 1000000007
using namespace std; long long dp[maxn],f[maxn][]; int main()
{
int t,n,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
memset(dp,,sizeof dp);
memset(f,,sizeof f);
f[][]=;
dp[]=;
for(int i=;i<n;i++)
{
for(int j=;j<=k;j++)
for(int v=;i-v>=j-;v++)
f[i][j]=(f[i][j]+dp[v]*f[i-v][j-])%mod;
for(int j=;j<=k;j++)
dp[i+]=(dp[i+]+f[i][j])%mod;
}
printf("%lld\n",dp[n]);
}
return ;
}
上一篇:CSS Selector (part 1)


下一篇:JavaScript 教程学习进度备忘(二)