版权声明:转载需要注明哦QwQ,地址:http://blog.csdn.net/effervescence。 https://blog.csdn.net/Effervescence/article/details/82289980
分析
考虑DP, 表示前 行里有 列可以填 ,有 列可以填 ,然后我们有 种转移:
(1)什么都不填,有 种方法,即 ;
(2)在前面几列中某一列填 ,有 种方法,即 ;
(3)在前面几列中某一列原来可以填 的列上填 ,有 种方法,即 ;
(4)在前面几列中某一列原来可以填 的列上填 ,有 种方法,即 ;
(5)在前面几列中某两列原来可以填 的列上填 ,有 种方法,即 ;
(6)在前面几列中某两列原来可以填 的列上填 ,有 种方法,即 ;
(7)分别在一列原来可以填 的列和原来可以填 的列上填 ,有 种方法,即 。
最后答案就是 。
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;
}