HihoCoder 1579 组合数学

题意

问符合一个后缀数组的小写字符串组合有多少种

题解

首先观察后缀数组,4 3 2 5 1。可以得到一些信息:
1、4<3<2<5<1一定是符合的
2、至于等号关系需要判断该位置后面的字符串与下一个位置后面字符串的关系,如果该位置后面字符串>下一个位置后面字符串,那么等号一定无法取到
3、关于后面字符串大小的判断,我们可以再次利用后缀数组进行判断,我们可以搞一个数组,记录以X开始的后缀在数组中的位置。
4、我们可以记录一下小于号的个数,如果小于号>=26,那么无解
之后就是一个组合数学问题了,由于有些地方可以取到等号,而有些地方不可以,我们可以将这个问题转化为允许部分空盒子的隔板问题(有小球26+1个,一个隔板代表一个位置,取隔板前小球代表的字符,补一个小球,使得隔板可以选到’z’,利用空盒子隔板法的思想还要再补K个小球,这里不再阐述)。于是可以利用公式C(n,26+k)求出答案(N为字符个数,K等号个数)。

代码

cs=int(input())
for s in range(cs):
    n=int(input())
    # print n
    li=list(map(lambda x:x-1,map(int,raw_input().split())))
    rev=[0]*(n+1)
    rev[n]=-1
    sum=0
    for i in range(n):
        rev[li[i]]=i
    for i in range(n-1):
        if rev[li[i]+1]>rev[li[i+1]+1]:
            sum+=1
    # print sum
    ans=1
    if sum>=26:
        print 0
    else:
        k=n-1-sum
        for i in range(26+k,n,-1):
            ans*=i
        for i in range(1,26+k-n+1):
            ans/=i
        print ans
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值