Codeforces Round #315 (Div. 2) D. Symmetric and Transitive

来源:互联网 发布:诈骗软件怎么举报 编辑:程序博客网 时间:2024/06/05 01:16


枚举能推出其的i个相等的元素(i<n 组合c[n,i]),其它n - i个元素都不能推出的个数;也就是sum(c[n][i] * dp[i][i]);这个公式的意思就是随便选i个,再把这i个元素分成i个集合的个数。

c[i,j]是组合数,直接用组合数的关系c[i,j] = c[i-1,j-1] + c[i-1,j]求出。

dp[i,j]是 斯特林数 也是贝尔数用公式也就是贝尔矩阵 dp[i][j] = (dp[i][j-1] + dp[i-1][j-1]);也可以求出。

#include<stdio.h>#include<string.h>#include<math.h>#include<queue>#include<vector>#include<iostream>#include<string>#include<set>#include<map>#include<algorithm>using namespace std;#pragma comment(linker, "/STACK:1024000000,1024000000")#define nn 10010#define ll long long#define ULL unsiged long long#define mod 1000000007#define inf oxfffffffffff#define lson l,mid,rt<<1#define rson mid+1,r,rt<<1|1//        ((`'-"` `""-'`))//         ) -  -  (//        /  (o _ o)  \//        \  ( 0 )  ///       _'-.._ '=' _..-'_//      /`;#'#'#. -. #'#'#;`\//      \_))   '#'   ((_///      #.  ☆ ☆ ☆  .#//      '#.  求 A C!  .#'//       /'#.     .#'\//       _\\'#.   .#'//_//       (((___)'#'(___)))ll dp[4040][4040],c[4040][4040];void init(){    dp[0][0]=dp[1][1]=1;    for(int i=1;i<4040;i++)    {        dp[i][1]=dp[i-1][i-1];        for(int j=2;j<=i;j++)            dp[i][j]=(dp[i][j-1]+dp[i-1][j-1])%mod;    }    for(int i=1;i<4040;i++)    {        c[i][0]=c[i][i]=1;        for(int j=1;j<i;j++)        {            c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;        }    }}int main(){    int n;    init();    while(~scanf("%d",&n))    {        ll ans=0;        for(int i=0;i<n;i++)        {            ans+=c[n][i]*dp[i][i];            ans%=mod;        }        cout<<ans<<endl;    }    return 0;}

0 0