Problem F. 集合划分
时间限制 1000 ms
内存限制 64 MB
题目描述
n个元素的集合{1,2,..., n }可以划分为若干个非空子集。例如,当n=4 时,集合{1,2,3,4}可以划分为15 个不同的非空子集如下:
{{1},{2},{3},{4}},
{{1,2},{3},{4}},
{{1,3},{2},{4}},
{{1,4},{2},{3}},
{{2,3},{1},{4}},
{{2,4},{1},{3}},
{{3,4},{1},{2}},
{{1,2},{3,4}},
{{1,3},{2,4}},
{{1,4},{2,3}},
{{1,2,3},{4}},
{{1,2,4},{3}},
{{1,3,4},{2}},
{{2,3,4},{1}},
{{1,2,3,4}}
给定正整数n,计算出n 个元素的集合{1,2,..., n }可以划分为多少个不同的非空子集。
输入数据
多组输入(<=10组数据,读入以EOF结尾) 每组一行输入一个数字,n(0<n<=18)
输出数据
每组输出一行结果。
样例输入
4
样例输出
15
思路解析:
有两种情况 第一种情况:对于n-1个数,m-1个集合,新来的数作为单独集合加进去,*1,第二种情况,对于n-1个数,m个集合,新来的数分别加到m个集合中,*m
其实,可以画个表的,一般动态规划的题,画个表很容易就解决了。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<math.h>
using namespace std;
long long recursion(int n, int m)
{
if(m==1)//m等1,则这种情况return1
return 1;
if(n<m)//不存在这种情况
return 0;
//有两种情况 第一种情况:对于n-1个数,m-1个集合,新来的数作为单独集合加进去,第二种情况,对于n-1个数,m个集合,新来的数分别加到m个集合中,
return recursion(n-1,m-1)+recursion(n-1,m)*m;
}
int main()
{
ios::sync_with_stdio(false);
int n;
while(cin>>n)
{
long long result=0;
for(int i=1;i<=n;i++)
result+=recursion(n,i);
cout<<result<<endl;
}
return 0;
}