codeforces 568B B. Symmetric and Transitive(贝尔数+组合数学)

题目链接:

codeforces


题目大意:

给出n,代表集合元素个数,求出满足传递性和对称性但不满足自反性的集合的数目。


题目分析:

我们可以将这个集合看作一个无向图,也就是对于每个联通块当中的点都是满足这三个性质的。所以所有不符合要求的就是我们选取图中的一些点(但不能是全部的点),然后对他们进行划分,也就是集合的划分的数目。(划分出的每个集合是一个联通块),而集合的划分数目正好就是贝尔数。


AC代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define MAX 4007

using namespace std;
typedef long long LL;

int n;

LL c[MAX][MAX];
LL b[MAX][MAX];
const LL mod = 1e9+7;

void init ( )
{
    c[0][0] = c[1][0] = c[1][1] = 1;
    for ( int i = 2 ; i < MAX ; i++ )
        for ( int j = 0 ; j <= i ; j++ )
            if ( j == 0 || j == i ) c[i][j] = 1;
            else
            {
                c[i][j] = c[i-1][j] + c[i-1][j-1];
                c[i][j] %= mod;
            }
    b[0][0] = b[1][1] = 1;
    for ( int i = 2 ; i < MAX ; i++ )
    {
        b[i][1] = b[i-1][i-1];
        for ( int j = 2 ; j <= i ; j++ )
        {
            b[i][j] = b[i][j-1] + b[i-1][j-1];
            b[i][j] %= mod;
        }
    }
}

int main ( )
{
    init ( );
    while ( ~scanf ( "%d" , &n ) )
    {
        LL ans = 0;
        for ( int i = 0 ; i < n ; i++ )
        {
            ans += c[n][i]*b[i][i]%mod;
            ans %= mod;
        }
        printf ("%I64d\n" , ans );
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值