HDU-4372 Count the Buildings

来源:互联网 发布:西翥灵仪 昆明知乎 编辑:程序博客网 时间:2024/05/22 04:37

题意:有一系列的楼房,高度从1~n,然后从左侧看能看到f个楼房,右侧看能看到b个楼房,问有多少个方案数满足。
思路:首先就是最高的房屋,我们不管从哪看都会看到的。
那么我们把剩下的房屋分成f-1组和b-1组,也就是分别放左边和右边。每一组的情况:f-1组确保每组最高的在左边就可以。这里它的顺序其实就是任意的圆排列了。同理b-1组的每组最高的在右边就可以了。
我们知道把n个元素分成k个圆排列的方案数是第一类斯特林数。
所以最终答案就是:
S1(n1,f1+b1)Cf1f1+b1

#include <cstdio>#include <queue>#include <cstring>using namespace std;const int MAXN = 2000+5;const int mod = 1e9+7;typedef long long LL;int s1[MAXN][MAXN];int c[MAXN][MAXN];void init(){    s1[1][1] = 1;    for(int i = 2; i <= 2000; ++i)        for(int j = 1; j <= i; ++j)        {            s1[i][j] = (s1[i-1][j-1] + (LL)s1[i-1][j]*(i-1)%mod)%mod;        }    for(int i = 0; i <= 2000; ++i)        for(int j = 0; j <= i; ++j)        {            if(!i || i == j)c[i][j] = 1;            else c[i][j] = (c[i-1][j-1] + c[i-1][j])%mod;        }}int main(){    init();    int t;    scanf("%d",&t);    int n,f,b;    while(t--)    {        scanf("%d%d%d",&n,&f,&b);        int m = f-1+b-1;        if(m > n-1)        {            puts("0");            continue;        }        int ans = (LL)s1[n-1][m]*c[m][f-1]%mod;        printf("%d\n",ans);    }    return 0;}
原创粉丝点击