题目大意
如图
Data Constraint
n≤50
题解
有一个叫prufer序列的东西
一个
n
个点的树会和一个长度为
然后就可以考虑构造prufer序列来求方案。
设
fi,j,k
表示处理完前
i
个点,树中已经
最后对于
时间复杂度: O(n4)
SRC
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std ;
#define N 50 + 10
typedef long long ll ;
const int MO = 1e9 + 7 ;
int a[N] ;
ll f[N][N][N] ;
ll fac[N] , _fac[N] ;
int T , n , maxd , ret ;
int Power( int x , int k ) {
int s = 1 ;
while ( k ) {
if ( k & 1 ) s = (ll)s * x % MO ;
x = (ll)x * x % MO ;
k /= 2 ;
}
return s ;
}
ll C( int n , int m ) { return (ll)fac[n] * _fac[m] % MO * _fac[n-m] % MO ; }
int main() {
freopen( "a.in" , "r" , stdin ) ;
freopen( "a.out" , "w" , stdout ) ;
fac[0] = _fac[0] = 1 ;
for (int i = 1 ; i <= 50 ; i ++ ) {
fac[i] = fac[i-1] * i % MO ;
_fac[i] = Power( fac[i] , MO - 2 ) ;
}
scanf( "%d" , &T ) ;
while ( T -- ) {
scanf( "%d" , &n ) ;
for (int i = 1 ; i <= n ; i ++ ) scanf( "%d" , &a[i] ) ;
memset( f , 0 , sizeof(f) ) ;
f[0][0][0] = 1 ;
for (int i = 1 ; i <= n ; i ++ ) {
for (int j = 0 ; j <= i ; j ++ ) {
for (int k = 0 ; k <= n ; k ++ ) {
f[i][j][k] = f[i-1][j][k] ;
if ( j ) {
for (int l = 0 ; l <= min( a[i] - 1 , k ) ; l ++ ) {
f[i][j][k] = (f[i][j][k] + (ll)f[i-1][j-1][k-l] * C( k , l ) % MO) % MO ;
}
}
}
}
}
printf( "%d " , n ) ;
for (int i = 2 ; i <= n ; i ++ ) printf( "%lld " , f[n][i][i-2] ) ;
printf( "\n" ) ;
}
return 0 ;
}
以上.