欢乐暑假线上编程比赛第三题:轮换数

题目详情

把n各事物的集合划分成k个非空子集的方式数,比如{1,2,3,4}划分2个非空子集,我们可以得到7种划分方式:

{1,2,3}U{4};{1,2,4}U{3};{1,3,4}U{2};{2,3,4}U{1};{1,2}U{3,4};{1,3}U{2,4};{1,4}U{2,3}.相信大家一看就知道这

个怎么做吧,因为这就是著名的Striling数.但是今天的问题却是,计算n个元素安排城k个轮换(而不是子集)的

方式数.轮换是循环排列,也就是[A,B,C,D]=[B,C,D,A]=[C,D,A,B]=[D,A,B,C];而另一方面轮换[A,B,C,D]不同

于[A,B,D,C]或[D,C,B,A].那么比如给定四个元素[1,2,3,4]我们可以得到11种不同方式形成2个轮换:[1,2,3][4];

[1,2,4][3];[1,3,4][2];[2,3,4][1];[1,3,2][4];[1,4,2][3];[1,4,3][2];[2,4,3][1];[1,2][3,4];[1,3][2,4];[1,4][2,3] 现在

给出n个元素,求出k个非空的轮换数

输入格式:

多组数据,每组数据一行包含两个整数,n和k (1<=k<=n<=500)。

输出格式:

结果对2014取余数的最终结果



答题说明

输入样例

1 1

输出样例:

1


思路:动态规划。对于每个轮换,我们可以将它旋转使它里面的最小元素在最前面,称这种形式为最小表示。

判断两个轮换是否相同只需要通过旋转把它们里面最小的元素移到最前面,然后看最小表示是否相同。n个元

素的k轮换,假设这k个轮换每个轮换的最小元素是mi,其中1<=i<=k,由于轮换与轮换之间的位置无关,所

以我们假设对于i < j, 有mi < mj,则1到mj - 1这些元素肯定不在第j个轮换,假设k个轮换的元素从左到右存

放在数组array[n]当中。假设dp[i][j]表示前i个元素形成j个轮换的数量,则有可能前j-1个元素形成了前j-1个轮

换,或者前j个元素形成了前j-1个轮换,或者前j+1......。假设前t个元素形成了前j-1个轮换,那么对于第j个轮换

最小元素为t+1,对于后面的t+2到i这些元素,由于他们的摆放对j个轮换的最小元素没有影响,所以他们可以随

意摆放,即我们可以先将它们摆放在数组array中,所以有递推公式:

              


源代码(C++):


                                  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值