设 f[i][j][0/1] 表示前i个数有j个非法的,i是否与i-1相邻的方案数,转移看代码吧。。
#include <bits/stdc++.h>
using namespace std;
#define N 1100
#define mod 7777777
#define ll long long
int f[N][N][2],n;
void upd(int &x,int y){x=(x+y)%mod;}
int main()
{
//freopen("tt.in","r",stdin);
scanf("%d",&n);
f[1][0][0]=1;
for(int i=1;i<n;i++)
for(int j=0;j<i;j++)
{
upd(f[i+1][j+1][1],f[i][j][0]*2%mod);
if(j)upd(f[i+1][j-1][0],(ll)f[i][j][0]*j%mod);
upd(f[i+1][j][0],(ll)f[i][j][0]*(i-1-j)%mod);
upd(f[i+1][j+1][1],f[i][j][1]);
upd(f[i+1][j][1],f[i][j][1]);
if(j)upd(f[i+1][j-1][0],(ll)f[i][j][1]*(j-1)%mod);
upd(f[i+1][j][0],(ll)f[i][j][1]*(i-j)%mod);
}
printf("%d\n",f[n][0][0]);
return 0;
}