题意:
符合下列条件的n*n的矩阵有多少个?(mod m)
每个元素只能为0,1,2;
对称矩阵,主对角线都为0;
每行的和为2。
思路:
看到矩阵的这些特征可以想到把它看作一个无向图的邻接矩阵。
若表示i和j之间有两条边,就相当于是两个点的环。
那么每行的和为2的意思就是每个点的度为2,说明这个图全部都是环,每个点属于且仅属于一个环。
可以考虑dp:
f(n)表示n个点时的方案数。
转移:
第n个点在二个点的环内的方案数:;
第n个点在三个点的环内的方案数:;
第n个点在四个点的环内的方案数:;
……
第n个点在k个点的环内的方案数:。
所以,
令,得
令,得
。
。
两式相减,得
。
将代入,得
。
就可以做了。
代码:
typedef long long ll;
ll f[100010];
int main()
{
ll n,m;
f[0]=1;f[1]=0;f[2]=1;f[3]=1;
while(scanf("%lld%lld",&n,&m)!=EOF)
{
if(n<=3){printf("%lld\n",f[n]);continue;}
for(ll i=4;i<=n;i++)
f[i]=(((i-1)*(f[i-1]+f[i-2])%m)%m-(((i-1)*(i-2)/2)%m*f[i-3])%m+m)%m;
printf("%lld\n",f[n]);
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!