zoukankan      html  css  js  c++  java
  • 「JSOI2013」游戏中的学问

    「JSOI2013」游戏中的学问

    传送门

    考虑 ( ext{DP})

    (dp_{i, j}) 表示将前 (i) 个人分成 (j) 个集合,并且第 (i) 个人在第 (j) 个集合的方案数。

    转移就是:

    [dp_{i, j} = dp_{i - 1, j} imes (i - 1) + dp_{i - 3, j - 1} imes {i - 1 choose 2} imes 2 ]

    其中前面那一项就是加入一个人,感觉有点像第一类斯特林数递推式中的一部分。。。

    然后后面那一项就是我们新开一个集合,强制 (i) 在这个集合中,然后再随便选两个人来组成一个圈,因为 (3) 个人的圆排列个数是 (2) 所以还要乘个 (2)

    #include <cstdio>
    #define rg register
    #define file(x) freopen(x".in", "r", stdin), freopen(x".out", "w", stdout)
    template < class T > inline void read(T& s) {
        s = 0; int f = 0; char c = getchar();
        while ('0' > c || c > '9') f |= c == '-', c = getchar();
        while ('0' <= c && c <= '9') s = s * 10 + c - 48, c = getchar();
        s = f ? -s : s;
    }
     
    const int _ = 3005;
     
    int n, k, p, dp[_][_ / 3 + 5];
     
    int main() {
    #ifndef ONLINE_JUDGE
        file("cpp");
    #endif
        read(n), read(k), read(p);
        dp[0][0] = 1;
        for (rg int i = 3; i <= n; ++i)
        	for (rg int j = 1; j <= i && j <= k; ++j) {
    	        dp[i][j] = (dp[i][j] + 1ll * dp[i - 1][j] * (i - 1) % p) % p;
    	        dp[i][j] = (dp[i][j] + 1ll * dp[i - 3][j - 1] * (i - 1) % p * (i - 2) % p) % p;
        	}
        printf("%d
    ", dp[n][k]);
        return 0;
    }
    
  • 相关阅读:
    毕设进度28
    任务27
    任务26
    任务25
    任务24
    第二次冲刺
    课堂作业-搜狗输入法
    课堂作业-寻找水王
    博客花园典型用户和场景
    第十天
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/12283597.html
Copyright © 2011-2022 走看看