[FJOI2016]建筑师

Posted lizehon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[FJOI2016]建筑师相关的知识,希望对你有一定的参考价值。

[Luogu4609]

斯特林数和组合数的应用 , 写得很好的题解

注意到建筑高度不同且取满\([1,n]\)

把所有的建筑分成 \(A+B-1\) 个部分 , \(n\)是最高点 , 把除了 \(n\) 以外的 \(n-1\)个建筑放到 \(A+B-2\)个圆桌上

相当于从高往低插入 , 可以选择独占一桌 , 即形成一个高峰 ; 或者补充到某一桌(块)某一人(楼)旁边 , 也就不会被看到

然后\(A+B-2\)个部分要选出\(A-1\)个放在左边,\(B-1\)个放在右边

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
const int INF=1e9+7;
inline LL read(){
    register LL x=0,f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
    return f*x;
}

const int SS=50005;
const int N=205;
const int mod=1e9+7;

int S[SS][N],C[N][N];
int T,n,a,b;

inline int add(int x,int y){x+=y;return x>mod?x-mod:x;}
inline int mul(LL x,int y){x*=y;return x>mod?x%mod:x;}

int main(){
    S[0][0]=S[1][1]=1;
    for(int i=2;i<SS;i++) S[i][1]=S[i-1][1]*(i-1);
    for(int i=2;i<SS;i++){
        for(int j=1;j<N&&j<=i;j++)
            S[i][j]=add(S[i-1][j-1],mul(S[i-1][j],i-1));
    }
    for(int i=0;i<N;i++) C[i][0]=1;
    for(int i=1;i<N;i++){
        for(int j=1;j<=i;j++)
            C[i][j]=add(C[i-1][j],C[i-1][j-1]);
    }
    T=read();
    while(T--){
        n=read(),a=read(),b=read();
        printf("%d\n",mul(S[n-1][a+b-2],C[a+b-2][a-1]));
    }
}

以上是关于[FJOI2016]建筑师的主要内容,如果未能解决你的问题,请参考以下文章

[FJOI2016] 建筑师

loj2173 「FJOI2016」建筑师

[FJOI2016]建筑师

FJOI2016 建筑师 和 CF960G Bandit Blues

[Luogu4609][FJOI2016]建筑师

[题解] [FJOI2016] 建筑师