usaco奶牛家谱

这题没做出来。。。


首先分析题目,嗯,没错这是个dp

n<=200; O(n^3)算法,确定了

每个树的状态都由其左右子树状态决定,根据乘法原理,其状态数等于左右子树状态数乘积

dp思路分析:设f[i,j]表示的是深度<=j,不仅是等于j,j以内的所有深度只要节点为i的方案数。

我们都知道一棵树,是由一个根节点+左子树+右子数。划分阶段当然是按树的深度和节点数来划分。

设这一棵树有m个节点,左子树有k个节点,则右子树有m-k-1个节点,f[i,j]:=f[i,j]+f[k,j-1]*f[i-k-1,j-1].

因为最后答案求的是深度为k的值,并不是<=k的值,所以应该是f[n,k]-f[n,k-1]

但是在每一个阶段的取模中,有可能会导致f[n,m]<f[n-1,m]对于这种情况,只需把f[n,m]+maxn-f[n-1,m]即可。


#include<algorithm>
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
using namespace std;
int n,k,dp[5000][5000]={0};
int main()
{
	scanf("%d%d",&n,&k);
	for (int i=1;i<=k;i++) dp[1][i]=1;
	for (int i=1;i<=k;i++)
	{
		for (int j=1;j<=n;j+=2)
		for (int l=1;l<=j-2;l++) dp[j][i]=(dp[j][i]+dp[l][i-1]*dp[j-l-1][i-1])%9901;
	}
	printf("%d",(dp[n][k]+9901-dp[n][k-1])%9901);
	return 0;
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值