在Python中查找从Ajob序列选择序列的方法数量

在Python中查找从Ajob序列选择序列的方法数量

假设有一种叫做Ajob语言的奇怪语言。它有无限数量的字母。我们知道该语言中的n个单词。第一个单词是一个字符长,第二个单词是两个字符长,依此类推。每个单词中的所有字母都是唯一的。如果我们从其中选择任何一个单词并形成一个子序列。子序列的长度应该比原始单词的长度小k。例如,如果所选单词的长度为L,则子序列的长度应为(L-k)。如果长度小于k的单词,则不应选择该单词。当它们的长度不同时或它们在相同位置包含不同字符时,两个子序列彼此不同。我们必须找到p作为模数的结果,其中p是一个素数。

因此,如果输入类似于n = 6,k = 5,p = 11,则输出将为7。

为此,我们将按照以下步骤进行操作 –

  • 创建一个空字典memo
  • n:= n + 1,k:= k + 1
  • fact:=具有一个元素1的列表
  • 对于i在范围1到p – 1中,执行
    • 将(事实的最后一个元素* i mod p)插入事实的末尾
  • 如果memo中存在p,则
    • inv_fact:= memo[p]
  • 否则,
    • inv:=具有两个元素0和1的列表
    • 对于i在范围2到p – 1中,执行
      • 将(p – floor of p/i * inv[p mod i] mod p)插入inv的末尾
    • inv_fact:=具有一个元素1的列表
    • 对于i在范围1到p – 1中,执行
      • 将(inv_fact的最后一个元素* inv[i] mod p)插入inv_fact的末尾
    • memo[p]:= inv_fact
  • 结果:= 1
  • 当n> 0时,
    • n1:= n mod p
    • k1:= k mod p
    • 如果k1 > n1,则
      • 返回0
    • 结果:=结果事实[n1] inv_fact[k1]* inv_fact[n1-k1] mod p
    • n:=(n/p的底数)
    • k:= floor of k/p
  • 返回结果

示例

让我们看一下以下实现以获得更好的理解 –

memo = {}
def solve(n, k, p):
   n += 1
   k += 1
   fact = [1]
   for i in range(1, p):
      fact.append(fact[-1] * i % p)
   if p in memo:
      inv_fact = memo[p]
   else:
      inv = [0, 1]
      for i in range(2, p):
         inv.append(p - p // i * inv[p % i] % p)
      inv_fact = [1]
      for i in range(1, p):
         inv_fact.append(inv_fact[-1] * inv[i] % p)
      memo[p] = inv_fact
   ret = 1
   while n > 0:
      n1 = n% p
      k1 = k % p
      if k1 > n1:
         return 0
      ret = ret * fact[n1] * inv_fact[k1] * inv_fact[n1 - k1] % p
      n //= p
      k //= p
   return ret

n = 6
k = 5
p = 11
print(solve(n, k, p))

输入

6, 5, 11

输出

7

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程