[FJOI2016]建筑师

一道好♂玩的题。

考虑怎么才能让这个序列满足条件。

考虑到这个高度是个n的排列,然后我们可以发现n一定是左右都可见的,然后就可以认为左边的前缀max有A-1个值,右边的后缀max有B-1个值。

可以认为成从n-1个数中取A+B-2个数组成一个圆排列,A-1个放左边。

所以这样的话答案就是strling[n-1][A+B-2]*C[A+B-2][A-1]。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int mod=1e9+7;
long long strling[50005][205],C[205][205];
int main() {
    C[0][0]=1;
    for(int i=1;i<=200;i++) {
        C[i][0]=1;
        for(int j=1;j<=i;j++) {
            C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
        }
    }
    strling[0][0]=1;
    for(int i=1;i<=50000;i++) 
        for(int j=1;j<=200;j++) 
            strling[i][j]=(strling[i-1][j-1]+strling[i-1][j]*(i-1))%mod;
    unsigned int T;
    int n,A,B;
    cin>>T;
    while(T--) {
        scanf("%d%d%d",&n,&A,&B);
        printf("%d\n",(1ll*strling[n-1][A+B-2]*C[A+B-2][A-1])%mod);
    }
    return 0;
}
[FJOI2016]建筑师

猜你喜欢

转载自www.cnblogs.com/sdfzhsz/p/9757558.html