传送门
解法1:
膜题解,分类讨论题
考虑设(f[i][j][0/1])表示填了(i)个数,前(i)个数相邻的有(j)对,(i)和(i-1)是否相邻
然后就是对于每次插进来一个数疯狂的分类讨论去转移就行了。
其实知道状态后面的方程就不难推了,随便推推就AC了
解法2:
猜测有规律,打表。看不出规律怎么办?
oeis
然后发现有一个很小清新的递推式,抄下来就AC了
不知道怎么推,估计是容斥吧
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
void read(int &x) {
char ch; bool ok;
for(ok=0,ch=getchar(); !isdigit(ch); ch=getchar()) if(ch=='-') ok=1;
for(x=0; isdigit(ch); x=x*10+ch-'0',ch=getchar()); if(ok) x=-x;
}
#define rg register
const int maxn=1010,mod=7777777;
int n,m,f[maxn][maxn][2];
int mul(int x,int y){return 1ll*x*y-1ll*x*y/mod*mod;}
int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int del(int x,int y){return x-y<0?x-y+mod:x-y;}
int main(){
read(n),f[1][0][0]=1;
for(rg int i=2;i<=n;i++)
for(rg int j=0;j<i;j++){
f[i][j][1]=add(add(f[i-1][j][1],f[i-1][j-1][1]),mul(f[i-1][j-1][0],2));
f[i][j][0]=add(mul(j,f[i-1][j+1][1]),mul(i-1-j,f[i-1][j][1]));
f[i][j][0]=add(f[i][j][0],add(mul(j+1,f[i-1][j+1][0]),mul(i-2-j,f[i-1][j][0])));
}
printf("%d
",f[n][0][0]);
}