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
  • 相关阅读:
    PHP获取一周的日期
    关系型数据库和非关系型数据库的区别和特点
    关系型数据库和非关系型数据库的特性以及各自的优缺点
    什么是数据库?什么是关系数据库?什么是非关系型数据库?
    PHP中把对象转数组的几个方法
    验证银行卡号
    xss过滤方法
    PHP 随机字符
    计算两个日期相差年月日
    判断一个时间段是否包含周末
  • 原文地址:https://www.cnblogs.com/Emcikem/p/14632995.html
Copyright © 2011-2022 走看看