bzoj 1801: [Ahoi2009]chess 中国象棋
f[i][j][k]表示i行之前有j行放了一个,k行放了两个棋子的方案数,DP。
代码懒得写了,copy了搞神的
1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstring> 5 using namespace std; 6 #define maxn 105 7 #define mod 9999973 8 #define rep(x,l,r) for (x=l;x<=r;x++) 9 long long f[maxn][maxn][maxn],ans=0; 10 inline long long C(long long x){return x*(x-1)/2;} 11 int n,m; 12 int main() 13 { 14 int i,j,k; 15 scanf("%d%d",&n,&m); 16 f[0][0][0]=1; 17 rep(i,1,n) rep(j,0,m) rep(k,0,m-j) 18 { 19 f[i][j][k]=f[i-1][j][k];//0 20 if (j) f[i][j][k]+=f[i-1][j-1][k]*(m-j-k+1);//1 21 if (k&&j<m) f[i][j][k]+=f[i-1][j+1][k-1]*(j+1); 22 if (j>1) f[i][j][k]+=f[i-1][j-2][k]*C(m-j-k+2);//2 23 if (j&&k) f[i][j][k]+=f[i-1][j][k-1]*(m-j-k+1)*j; 24 if (k>1&&j<m-1) f[i][j][k]+=f[i-1][j+2][k-2]*C(j+2); 25 if (f[i][j][k]>=mod) f[i][j][k]%=mod; 26 } 27 rep(i,0,m) rep(j,0,m-i) ans+=f[n][i][j]; 28 if (ans>=mod) ans%=mod; 29 cout<<ans<<endl; 30 return 0; 31 }