百度笔试,排队问题

在一场运动会中有n个国家的队伍参赛,每支队伍5个运动员,所以一共有5n个运动员。现对这5n个运动员排成一列,要求每位远动员能够挨着他的同胞站,问有多少种排列组会方法,最后输出的答案除以1000000007取余即可。北邮人论坛链接

#这部分是通用的基础函数

def A(n):
    return n*A(n-1) if n>0 else 1

def C(n,m):
    return A(n)/(A(n-m)*A(m)) if m>0 else 1

def mod(n):
    return n%1000000007

def queue(n):
    sum = 0
    for i in range(n+1):
        sum = C(n,i)*A(n+i) - sum
    k = pow(120,n)
    return mod(mod(k)*mod(sum))

n = raw_input('input n:')
print queue(int(n))
方法二:用标准的容斥原理:
#这部分是通用的基础函数
def A(n):
    return n*A(n-1) if n>0 else 1

def C(n,m):
    return A(n)/(A(n-m)*A(m)) if m>0 else 1

def mod(n):
    return n%1000000007
#第二种写法
def queue(n):
    sum = 0
    for i in range(n+1):
        if i%2==1:
            sum -= A(2*n-i)*C(n,n-i)
        else:
            sum += A(2*n-i)*C(n,n-i)
    k=1
    for i in range(n):
        k = mod(k*120)
    return mod(mod(k)*mod(sum))
#这种写法是比较标准的容斥原理 由最全面的结果开始进行排除
#这部分是通用的基础函数
def A(n):
    return n*A(n-1) if n>0 else 1

def C(n,m):
    return A(n)/(A(n-m)*A(m)) if m>0 else 1

def mod(n):
    return n%1000000007

#第一种写法
def calc(i,n,s):
    if i==0:
        return A(n)*C(n,0)

    sum = A(n+i)*C(n,i)
    for j in range(i):
        sum -= s[j]*C(n-j,i-j)*pow(2,i-j)

    return sum

def queue(n):
    s = [0]*int(1e5)
    sum = 0
    for i in range(n+1):
        s[i] = calc(i,n,s)
        sum += s[i]

    k=1
    for i in range(n):
        k = mod(k*120)
    return mod(mod(k)*mod(sum))
#这种写法是计算n个国家5人相连,n-1个国家5人相连,一个国家2,3人相连等每种情况的有效排序,算是很麻烦了,不推荐


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值