我们不难发现,对于儿子层的点,假设有
x
x
x个点要求它的父亲链上对它的影响为+1,
y
y
y个点为-1,那么一个当前层的节点,如果儿子奇数位置为要求+1的点,那么当前点的要求就变成了-1,即我们可以通过儿子来推出父亲的要求。
不妨设
x
<
=
y
x<=y
x<=y,那么有
y
−
x
y-x
y−x个新点是奇数个的,剩下的新点的取值可以随便选择,枚举剩下的新点多少个选1,多少个选-1即可。因此我们可以知道,状态只需要记录
(
x
−
y
)
(x-y)
(x−y)即可。
O
(
n
4
)
O(n^4)
O(n4)
#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define maxn 51#define ll long long #define mo 1000000007
using namespace std;int n,i,j,k,l;
ll f[maxn][maxn][2],C[maxn][maxn],ans;intmain(){freopen("ceshi.in","r",stdin);scanf("%d",&n);for(C[0][0]=1,i=1;i<=n;i++)for(C[i][0]=1,j=1;j<=i;j++)
C[i][j]=(C[i-1][j-1]+C[i-1][j])%mo;
f[0][0][0]=1;for(i=0;i<n;i++)for(j=0;j<=i;j++)for(int p=0;p<2;p++)if(f[i][j][p]){int x=(p==1)*j,y=(p==0)*j;for(k=0;i+j+k<=n;k++)for(l=0;i+j+k+l<=n;l++)if(j+k+l>0)if(i+j+k+l<n||i+j+k+l==n&&j+k+l==1)(f[i+j+k+l][max(x+k,y+l)-min(x+k,y+l)][x+k<=y+l]+=f[i][j][p]*C[i+j+k+l][i]%mo*C[j+k+l][y+k])%=mo;}printf("%lld\n",f[n][1][0]);}