分析
考虑DP, f[i][j][k] f [ i ] [ j ] [ k ] 表示前 i i 行里有列可以填 1 1 ,有列可以填 2 2 ,然后我们有种转移:
(1)什么都不填,有 1 1 种方法,即;
(2)在前面几列中某一列填 2 2 ,有种方法,即 f[i+1][j][k]+=(k+1)∗f[i][j][k] f [ i + 1 ] [ j ] [ k ] + = ( k + 1 ) ∗ f [ i ] [ j ] [ k ] ;
(3)在前面几列中某一列原来可以填 2 2 的列上填,有 k+1 k + 1 种方法,即 f[i+1][j+1][k]+=(k+1)∗f[i][j][k] f [ i + 1 ] [ j + 1 ] [ k ] + = ( k + 1 ) ∗ f [ i ] [ j ] [ k ] ;
(4)在前面几列中某一列原来可以填 1 1 的列上填,有 j j 种方法,即;
(5)在前面几列中某两列原来可以填 2 2 的列上填,有 (k+1)∗k/2 ( k + 1 ) ∗ k / 2 种方法,即 f[i+1][j+2][k−1]+=(k∗(k+1)/2)∗f[i][j][k](k>0) f [ i + 1 ] [ j + 2 ] [ k − 1 ] + = ( k ∗ ( k + 1 ) / 2 ) ∗ f [ i ] [ j ] [ k ] ( k > 0 ) ;
(6)在前面几列中某两列原来可以填 1 1 的列上填,有 j∗(j−1)/2 j ∗ ( j − 1 ) / 2 种方法,即 f[i+1][j−2][k+1]+=(j∗(j−1)/2)∗f[i][j][k](j>1) f [ i + 1 ] [ j − 2 ] [ k + 1 ] + = ( j ∗ ( j − 1 ) / 2 ) ∗ f [ i ] [ j ] [ k ] ( j > 1 ) ;
(7)分别在一列原来可以填 2 2 的列和原来可以填的列上填 1 1 ,有种方法,即 f[i+1][j][k]+=(j∗(k+1))∗f[i][j][k] f [ i + 1 ] [ j ] [ k ] + = ( j ∗ ( k + 1 ) ) ∗ f [ i ] [ j ] [ k ] 。
最后答案就是 ∑i=0n∑j=0nf[n][i][j](i+j<=n) ∑ i = 0 n ∑ j = 0 n f [ n ] [ i ] [ j ] ( i + j <= n ) 。
Code
#include<bits/stdc++.h>
using namespace std;
const int mod=1e8+7;
namespace {
inline int Half(const int &x) {
return x&1?x+mod>>1:x>>1;
}
inline int Add(const int &x,const int &y) {
int res=x+y;
return res>=mod?res-mod:res;
}
inline int Sub(const int &x,const int &y) {
int res=x-y;
return res<0?res+mod:res;
}
inline int Mul(const int &x,const int &y) {
return 1ll*x*y%mod;
}
inline int C_2(const int &x) {
return Half(Mul(x,x-1));
}
}
int f[205][205][205],n;
int main() {
cin>>n;
f[0][0][0]=1;
for(int i=0;i<n;++i)
for(int j=0;j<=i;++j)
for(int k=0;k<=i;++k)
if(j+k<=i) {
/*Tramsform place Nothing:*/ {
f[i+1][j][k+1]=Add(f[i+1][j][k+1],f[i][j][k]);
}
/*Transform Place a two:*/ {
f[i+1][j][k]=Add(f[i+1][j][k],Mul(k+1,f[i][j][k]));
}
/*Transform Place a one in k*/ {
f[i+1][j+1][k]=Add(f[i+1][j+1][k],Mul(k+1,f[i][j][k]));
}
/*Tramsform Place a one in j*/ {
if(j)
f[i+1][j-1][k+1]=Add(f[i+1][j-1][k+1],Mul(j,f[i][j][k]));
}
/*Transform Place two one in j*/ {
if(j>1)
f[i+1][j-2][k+1]=Add(f[i+1][j-2][k+1],Mul((1ll*(j-1)*j/2)%mod,f[i][j][k]));
}
/*Transform Place a one in j and a one in k*/ {
if(j)
f[i+1][j][k]=Add(f[i+1][j][k],Mul(Mul(j,k+1),f[i][j][k]));
}
/*Transform Place two one in k*/ {
if(k)
f[i+1][j+2][k-1]=Add(f[i+1][j+2][k-1],Mul((1ll*(k+1)*k/2)%mod,f[i][j][k]));
}
}
int ans=0;
for(int j=0;j<=n;++j)
for(int k=0;k<=n;++k)
if(j+k<=n)
ans=Add(ans,f[n][j][k]);
cout<<ans<<endl;
}