1. 程式人生 > >[BZOJ4321]queue2(DP)

[BZOJ4321]queue2(DP)

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 }