[BZOJ4321]queue2(DP)
阿新 • • 發佈:2018-11-05
f[i][j]表示從小到大插入前i個數,有j個位置不合法(即有j對相鄰數)的方案數。
轉移時要考慮插入的位置以及i-1的情況,於是增設一維0/1/2記錄i-1和左邊的數相鄰/和右邊的數相鄰/不和兩邊相鄰。暴力轉移即可。
1 #include<cstdio> 2 #include<algorithm> 3 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 4 using namespace std; 5 6 const int N=1010,mod=7777777; 7 int n,f[N][N][3]; 8 9 int main(){ 10 freopen("bzoj4321.in","r",stdin); 11 freopen("bzoj4321.out","w",stdout); 12 scanf("%d",&n); f[1][0][0]=1; 13 rep(i,2,n) rep(j,0,i-1){ 14 f[i][j][0]=(f[i][j][0]+(1ll*f[i-1][j][0]*(i-2-j)+1ll*(f[i-1][j][1]+f[i-1][j][2])*(i-1-j))%mod)%mod; 15 f[i][j][0]=(f[i][j][0]+(1ll*f[i-1][j+1][0]*(j+1)+1ll*(f[i-1][j+1][1]+f[i-1][j+1][2])*j)%mod)%mod; 16 if (j) f[i][j][1]=((f[i][j][1]+f[i-1][j][2])%mod+(f[i-1][j-1][0]+f[i-1][j-1][1])%mod)%mod; 17 if (j) f[i][j][2]=((f[i][j][2]+f[i-1][j][1])%mod+(f[i-1][j-1][0]+f[i-1][j-1][2])%mod)%mod; 18 }19 printf("%d\n",f[n][0][0]); 20 return 0; 21 }