CF382E
orz sinsop90/bx
乌龟和 sinsop 结芬!!!
题意即数最大匹配为
考虑怎么设计状态:子树
于是设
考虑转移,首先枚举两棵子树大小
后面两个组合数是选定点的标号的方案数。
否则根没有被选,则两个子树至少有一个根没被选。则类似地,有:
两边不同时为
还有一点小问题,当
初始值为
code:
点击查看代码
int n,m,fac[N],ifac[N],dp[N][N][2];
il int Mod(int x,int y){return x+y>=mod?x+y-mod:x+y;}
il int binom(int x,int y){return 1ll*fac[x]*ifac[y]%mod*ifac[x-y]%mod;}
il int qpow(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod,y>>=1;
}
return ret;
}
void Yorushika(){
scanf("%d%d",&n,&m);
fac[0]=1;
rep(i,1,n)fac[i]=1ll*fac[i-1]*i%mod;
ifac[n]=qpow(fac[n],mod-2);
drep(i,n-1,0)ifac[i]=1ll*ifac[i+1]*(i+1)%mod;
dp[0][0][1]=dp[1][0][0]=1;
const int iv2=qpow(2,mod-2);
rep(i,1,n-1)rep(j,0,i/2){
rep(p,0,min(n-i,i))rep(q,0,p/2){//I love turtles(It's written by sinsop90!)
int x=i==p?iv2:1;
dp[i+p+1][j+q][0]=Mod(dp[i+p+1][j+q][0],1ll*dp[i][j][1]*dp[p][q][1]%mod*binom(i+p+1,i)%mod*binom(p+1,p)%mod*x%mod);
dp[i+p+1][j+q+1][1]=Mod(dp[i+p+1][j+q+1][1],1ll*dp[i][j][0]*dp[p][q][0]%mod*binom(i+p+1,i)%mod*binom(p+1,p)%mod*x%mod);
dp[i+p+1][j+q+1][1]=Mod(dp[i+p+1][j+q+1][1],1ll*dp[i][j][0]*dp[p][q][1]%mod*binom(i+p+1,i)%mod*binom(p+1,p)%mod*x%mod);
dp[i+p+1][j+q+1][1]=Mod(dp[i+p+1][j+q+1][1],1ll*dp[i][j][1]*dp[p][q][0]%mod*binom(i+p+1,i)%mod*binom(p+1,p)%mod*x%mod);
}
}
printf("%lld\n",1ll*Mod(dp[n][m][0],dp[n][m][1])*qpow(n,mod-2)%mod);
}
signed main(){
int t=1;
// scanf("%d",&t);
while(t--)
Yorushika();
}