Python中查找相邻k次交换且不多于k次交换后序列数量的程序

Python中查找相邻k次交换且不多于k次交换后序列数量的程序

假设我们有一个数组A,其中包含前n个自然数。现在,我们需要找到经过恰好k次相邻交换后可以得到多少个序列(S1)?同时,我们需要找到经过最多k次交换后可以得到多少个序列(S2)?这里的相邻交换是指交换索引i和i + 1处的元素。

那么,如果输入为n = 3,k = 2,则输出将是3,6,因为 –

原始数组是[1, 2, 3]

  • 经过2次相邻交换后:我们可以得到[1, 2, 3]、[2, 3, 1]、[3, 1, 2]。因此,S1 = 3
  • 经过最多2次交换后:
    • 经过0次交换:[1, 2, 3]
    • 经过1次交换:[2, 1, 3]、[3, 2, 1]、[1, 3, 2]。
    • 经过2次交换:[1, 2, 3]、[2, 3, 1]、[3, 1, 2]

因此,S2 = 6

要解决这个问题,我们需要按照以下步骤进行 –

  • p = 10 ^ 9 + 7
  • A:仅包含1个元素的数组
  • C:仅包含1个元素的数组
  • 对于n在2到n + 1的范围内,进行以下操作
    • B = A,A = 仅包含1个元素1的数组
    • D = C,C = 仅包含1个元素1的数组
    • 对于x在1到k + 1和1到n所有数字的总和的最小值之间的范围内,进行以下操作
      • (A的最后一个元素 + (当x小于B的大小时,B [x]否则0) – (当0 <= x-n时,B [x-n]否则0)) mod p,在A的末尾插入
    • 对于x在1到n-2之间的范围内,进行以下操作
      • 在C的末尾插入(D [x] +(n-1)* D [x-1])模p
    • 在C的末尾插入(n * D的最后一个元素)mod p
  • 返回A [从k mod 2到k的索引的所有元素之和]取模p和C [n-1和k的最小值]的总和

示例

看下面的实现,以获得更好的理解 –

p = 10**9+7
def solve(n, k):
   A = [1]
   C = [1]
   for n in range(2,n+1):
      B = A
      A = [1]
      D = C
      C = [1]

      for x in range(1,min(k+1,n*(n-1)//2+1)):
         A.append((A[-1] + (B[x] if x<len(B) else 0) - (B[x-n] if 0<=x-n else 0)) % p )
      for x in range(1,n-1):
         C.append((D[x]+(n-1)*D[x-1]) % p)
      C.append(n*D[-1] % p)
   return sum(A[k%2:k+1:2]) % p,C[min(n-1,k)]

n = 3
k = 2
print(solve(n, k))

输入

3,2

输出

3,6

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程