题目:
data游戏里面,召唤师可以控制冰雷火三种元素,并通过元素组合产生新的技能,现在我们修改了一张新的地图,地图中他能够控制n种元素,并且将m个元素围成一个圈组成一个新的技能(这m个元素通过旋转或反转,算作重复,如123、231、312、321、213、132都算重复),那么召唤师能组合多少技能(20000>=n>=1,1<=m<=10000),由于结果可能很大,请将结果对1000000007取余。例:
输入:
3 3
输出:
10
解析:111、112、113、122、123、133、222、223、233、333一共10种。
解答:
根据所给题目意思和示例,可知从n个种抽取m个数是可以抽到同一个数的。
从n个种抽m个数——抽到的数完全不同时有;
从n个种抽m个数——抽到的数有两个数相同时有,即:先从n个数中抽取一个数作为重复数,再从剩下的n-1个数种抽取m-2个不同的数;
从n个种抽m个数——抽到的数有三个数相同时有,即:先从n个数中抽取一个数作为重复数,再从剩下的n-1个数种抽取m-3个不同的数;
同理……
当从n个种抽m个数——抽到的数有m-1个数相同时有,即:先从n个数中抽取一个数作为重复数,再从剩下的n-1个数种抽取m-3个不同的数;
当从n个种抽m个数——抽到的数有m个数相同时有,即:先从n个数中抽取一个数作为重复数,再从剩下的n-1个数种抽取m-3个不同的数;
将全部情况相加便得到最终的结果。
#定义阶乘函数:n!
def D(n):
a=1
if n==1:
return 1
for i in range(1,n+1):
a=a*i
return a
#定义组合数计算函数:C(n,m)=n!/[m!*(n-m)!]
def C(n,m):
return (D(n)//(D(m)*D(n-m)))
n,m=input().split()
n=int(n)
m=int(m)
if 20000>=n>=1 and 1<=m<=10000:
num2=0
for i in range(m-1):
num2+=n*C(n-1,i)
num2+=C(n,m)
print(num2%1000000007)
然而,在写文章的时候,突然发现,这里忽略圈为划分重复组合的唯一一个限制条件,也就是说,当m大于3时候,存在其他满足条件的组合没有算进去,而这些组合并未重复,例如:
n=5,m=5时,12435与12345是不算重复的,而上面的方法缺少了对这类情况的考虑。。(我太难了)