首页 > 其他 > 详细

集合的划分

时间:2021-01-21 09:26:48      阅读:24      评论:0      收藏:0      [点我收藏+]

集合的划分(1)

【问题描述】
设S是一个具有n个元素的集合,S={a1,a2,……,an},现将S划分成k个满足下列条件的子集合S1,S2,……,Sk ,且满足:

 

技术分享图片
则称S1,S2,……,Sk是集合S的一个划分。它相当于把S集合中的n个元素a1 ,a2,……,an 放入k个(0<k≤n<30)无标号的盒子中,使得没有一个盒子为空。请你确定n个元素a1 ,a2 ,……,an 放入k个无标号盒子中去的划分数S(n,k)。
【输入样例】setsub.in
23 7
【输出样例】setsub.out
4382641999117305
【分析】本题首先想到用dp求解,状态S(n,k)题中已经设定好了,那么关键在于如何转移我们的状态;
(搜索貌似过不了,也不会写QAQ)
对于一个二维的状态dp[i][j],一般必须从i,j的先前状态转移,不能只转移一维,那么就需要进行分类
(1){an}单独放在一个盒子里面,只需要将dp[i-1][j-1]的情况求出(即i-1个球放在j-1个盒子里面)
(2)an放在其他的盒子里面,则先把a1~an-1放到j个盒子里,an再放进这j个盒子中,有j种方法。即dp[i-1][j]*j
根据加法原理,dp[i][j]=dp[i-1][j-1]+dp[i-1][j]*j;
别忘了初始化,当k=1时 ,dp[i][1]=1;
代码如下:
#include<bits/stdc++.h>
using namespace std;
int n,k;
int dp[35][35];
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
        dp[i][1]=1,dp[i][i]=1;
    for(int i=1;i<=n;i++)
        for(int j=2;j<=i;j++)
        {
            dp[i][j]=dp[i-1][j-1]+j*dp[i-1][j];
            //i球j盒 
        }
    printf("%d",dp[n][k]);
    return 0;
}

 

 

集合的划分

原文:https://www.cnblogs.com/conprour/p/14306107.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!