zoukankan      html  css  js  c++  java
  • 2018牛客多校第一场 B.Symmetric Matrix

    题意:

      构造一个n*n的矩阵,使得Ai,i = 0,Ai,j = Aj,i,Ai,1+Ai,2+...+Ai,n = 2。求种类数。

    题解:

      把构造的矩阵当成邻接矩阵考虑。

      那么所有点的度数都为2,且存在重边但不存在自环。这种情况的图为多个环,即每个点都在且仅在一个环里。

      考虑每次加一个点来递推dp[]。假设当前是第n个点,从前n-1个点中筛出(1~n-3)个点和第n个点形成环。

      设n-1个点中保留k个点,即筛出n-1-k个点和第n个点形成环。

      递推方程为:f(n) = (n-1)f(n-2)+sigma(k:2->n-3)C(n-1,k)f(k)(n-1-k)!/2;

      其中(n-1)f(n-2)为从n-1个点中筛出1个点的情况。C(n-1,k)为从n-1个点中筛出k个点的组合数(k表示保留的个数)。(n-1-k)!表示筛出的n-1-k个数与第n个数一共n-k个数构成环的种数。

      /2是因为去掉像1 2 3 4 和 1 4 3 2这种对称的情况。但是当k=1时就不用/2所以就把k=1的情况先写出来。

      然后就是化简递推方程。

      C(n-1,k)f(k)(n-1-k)!/2 = f(k)(n-1)!/k!/2

      f(n) = (n-1)f(n-2)+sigma(k:2->n-3)f(k)(n-1)!/k!/2

      (n-1)f(n-1) = (n-1)(n-2)f(n-3)+sigma(k:2->n-4)f(k)(n-1)!/k!/2

      减一下就变成:f(n) = (n-1)f(n-1)+(n-1)f(n-2)-(n-1)(n-2)f(n-3)/2

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5+10;
    typedef long long ll;
    int n, m;
    int dp[N];
    int main() {
        while(~scanf("%d%d", &n, &m)) {
            dp[1] = 0; dp[2] = 1%m; dp[3] = 1%m;
            for(int i = 4; i <= n; i++) dp[i] = ((1ll*(i-1)*dp[i-1]%m+1ll*(i-1)*dp[i-2]%m-1ll*(i-1)*(i-2)/2*dp[i-3]%m)%m+m)%m;
            printf("%d
    ", dp[n]);
        }
    }
    View Code

      

      

  • 相关阅读:
    12345679*81=?
    怪异,漂亮的几个数学恒等式(转)
    道路着色问题
    一组数学算式的欣赏(转)
    数学中奇妙的“金蝉脱壳”(转)
    数学中的分分合合(转)
    四方定理和卡布列克常数(转)
    简单的题目 有趣的现象
    Android学习笔记 第三节 基本控件学习
    Android学习笔记 第二节 HelloWorld程序
  • 原文地址:https://www.cnblogs.com/Pneuis/p/9341964.html
Copyright © 2011-2022 走看看