题目链接:
题目大意:
给出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 );
}
}