题意:

符合下列条件的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 协议 ,转载请注明出处!

HDU6299 贪心 Previous
io优化 Next