Codeforces Round 424 (Div. 1)D. Singer House

传送门

显然要自底向上进行\(dp\)

深度相同的子树结构相同所以可以利用深度来代表子树。

那么就应该统计出有向路径的个数。

考虑路径由链所拼成。那么状态里应该有有向链的条数。

\(f_{i,j}\)表示深度为\(i\)链条数为\(j\)的方案数。

不选当前的节点则\(f_{i,j}=f_{i+1,k}\cdot f_{i+1,j-k}\)

若当前节点自成一链则\(f_{i,j}=f_{i+1,k}\cdot f_{i+1,j-k-1}\)

若当前节点和其他链构成一链\(f_{i,j}=f_{i+1,k}\cdot f_{i+1,j-k}\cdot 2j\)

通过当前节点连接两条链\(f_{i,j-1}=f_{i+1,k}\cdot f_{i+1,j-k}\cdot j\cdot (j-1)\)

//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define inf 100000000000000000ll
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define putl_(x) printf("%lld ",x);
#define get(x) x=read()
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(int i=p;i<=n;i+=1)
#define fep(n,p,i) for(int i=n;i>=p;--i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define pii pair<int,int>
#define mk make_pair
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define sq sqrt
#define x(w) t[w].x
#define r(w) t[w].r
#define id(w) t[w].id
#define R(w) s[w].r
#define yy p<<1|1
#define zz p<<1
#define sum(w) t[w].sum
#define mod 1000000007
#define sc(A) scanf("%d",&A)
#define scs(A) scanf("%s",A);
#define put(A) printf("%d\n",A)
#define min(x,y) (x>=y?y:x)
#define max(x,y) (x>=y?x:y)
#define sub(x,y) (x-y<0?x-y+mod:x-y)
#define EPS 1e-7
using namespace std;
const int MAXN=410,G=(mod+1)>>1;
int n,m;
int f[MAXN][MAXN];
signed main()
{
	//freopen("1.in","r",stdin);
	sc(n);
	f[n][0]=f[n][1]=1;
	fep(n-1,1,i)
	{
		rep(0,i+1,j)
		{
			rep(0,j,k)
			{
				f[i][j]=(f[i][j]+(ll)f[i+1][k]*f[i+1][j-k])%mod;
				if(j>k)f[i][j]=(f[i][j]+(ll)f[i+1][k]*f[i+1][j-k-1])%mod;
				f[i][j]=(f[i][j]+(ll)f[i+1][k]*f[i+1][j-k]%mod*2*j)%mod;
				if(j>=1)f[i][j-1]=(f[i][j-1]+(ll)f[i+1][k]*f[i+1][j-k]%mod*j%mod*(j-1))%mod;
			}
		}
	}
	put(f[1][1]);
	return 0;
}
posted @ 2023-08-04 11:19  chdy  阅读(11)  评论(0编辑  收藏  举报