2019华为某笔试题篇——事情没有那么简单?

题目:

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个数——抽到的数完全不同时有C_{n}^{m}

从n个种抽m个数——抽到的数有两个数相同时C_{n}^{1}C_{n-1}^{m-2}有,即:先从n个数中抽取一个数作为重复数,再从剩下的n-1个数种抽取m-2个不同的数;

从n个种抽m个数——抽到的数有三个数相同时C_{n}^{1}C_{n-1}^{m-3}有,即:先从n个数中抽取一个数作为重复数,再从剩下的n-1个数种抽取m-3个不同的数;

同理……

当从n个种抽m个数——抽到的数有m-1个数相同时C_{n}^{1}C_{n-1}^{1}有,即:先从n个数中抽取一个数作为重复数,再从剩下的n-1个数种抽取m-3个不同的数;

当从n个种抽m个数——抽到的数有m个数相同时C_{n}^{1}C_{n-1}^{0}有,即:先从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是不算重复的,而上面的方法缺少了对这类情况的考虑。。(我太难了)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章