zoukankan      html  css  js  c++  java
  • P4609 [FJOI2016]建筑师

    传送门

    转化为一个模型就是把(n)个不同的物品放进(m)个相同的盒子里,然后盒子里的物品进行圆排列,那么就是第一类斯特林数了

    假设从度为n的柱子已经确定了
    那么划分为两块了
    左边看,还需要选择A-1块建筑块,右边看,还需要选择(B-1)块建筑物
    在一个建筑块里面,如果一个标志物品(最高的那个)选择了,那么在左边就要放在最左边块,右边的话就要放在最右边块.
    那么对于大小为(k)的建筑块来说,有((k-1)!)种方案相当于是这一块进行圆排列
    类似于这种,每个建筑块里面都有一个标志物品,然后其他的物品进行全排列.相当于是这个建筑块进行园排列

    (n-1)个物品划分为(A+B-2)个建筑块然后每一块进行园排列.最后在这(A+B-2)个建筑块里面选择(A-1)个块放在左边

    #include <bits/stdc++.h>
    #define ll long long
    #define ld long double
    #define CASE int Kase = 0; cin >> Kase; for(int kase = 1; kase <= Kase; kase++)
    using namespace std;
    template<typename T = long long> inline T read() {
        T s = 0, f = 1; char ch = getchar();
        while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
        while(isdigit(ch)) {s = (s << 3) + (s << 1) + ch - 48; ch = getchar();} 
        return s * f;
    }
    #ifdef ONLINE_JUDGE
    #define qaq(...) ;
    #define qwq(c) ;
    #else
    #define qwq(a, b) for_each(a, b, [=](int x){cerr << x << " ";}), cerr << std::endl
    template <typename... T> void qaq(const T &...args) {
        auto &os = std::cerr;
        (void)(int[]){(os << args << " ", 0)...};
        os << std::endl;
    }
    #endif
    const int N = 2e5 + 5, M = 1e6 + 5, MOD = 1e9 + 7, CM = 998244353, INF = 0x3f3f3f3f; const ll linf = 0x7f7f7f7f7f7f7f7f;
    int C[305][305], S[50005][305];
    void solve(int kase){
        S[0][0] = C[0][0] = 1;
        for (int i = 0; i <= 300; i++) C[i][i] = C[i][0] = 1;
        for(int i = 1; i <= 300; i++) {
        	for(int j = 0; j <= i; j++) {
        		if(j == 0 || i == j) C[i][j] = 1;
        		else C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
        	}
        }
        for(int i = 1; i <= 50000; i++) {
        	for(int j = 1; j <= min(i, 300); j++) {
        		S[i][j] = (S[i - 1][j - 1] + 1ll * S[i - 1][j] * (i - 1) % MOD) % MOD;
        	}
        }
        int t = read();
        for(int i = 1; i <= t; i++) {
        	int n = read(), a = read(), b = read();
        	printf("%lld
    ", 1ll * S[n - 1][a + b - 2] * C[a + b - 2][a - 1] % MOD);
        }
    }
    const bool ISFILE = 0, DUO = 0;
    int main(){
        clock_t start, finish; start = clock();
        if(ISFILE) freopen("/Users/i/Desktop/practice/in.txt", "r", stdin);
        if(DUO) {CASE solve(kase);} else solve(1);
        finish = clock(); 
        qaq("
    Time:", (double)(finish - start) / CLOCKS_PER_SEC * 1000, "ms
    ");
        return 0;
    }
    
    I‘m Stein, welcome to my blog
  • 相关阅读:
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 382 链表随机节点
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 381 O(1) 时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Java实现 LeetCode 380 常数时间插入、删除和获取随机元素
    Linux下的iwpriv(iwlist、iwconfig)的简单应用
    OCX控件的注册卸载,以及判断是否注册
    .OCX、.dll文件注册命令Regsvr32的使用
  • 原文地址:https://www.cnblogs.com/Emcikem/p/14632995.html
Copyright © 2011-2022 走看看