数列还原

题目描述
牛牛的作业薄上有一个长度为 n 的排列 A,这个排列包含了从1到n的n个数,但是因为一些原因,其中有一些位置(不超过 10 个)看不清了,但是牛牛记得这个数列顺序对的数量是 k,顺序对是指满足 i < j 且 A[i] < A[j] 的对数,请帮助牛牛计算出,符合这个要求的合法排列的数目。
输入描述:
每个输入包含一个测试用例。每个测试用例的第一行包含两个整数 n 和 k(1 <= n <= 100, 0 <= k <= 1000000000),接下来的 1 行,包含 n 个数字表示排列 A,其中等于0的项表示看不清的位置(不超过 10 个)。
输出描述:
输出一行表示合法的排列数目。
示例1
输入
5 5
4 0 0 2 0
输出
2

这个题使用全排列去做,首先找到哪些数字尚未被使用,然后对这些数组进行全排列,注意,这里空缺数字不会超过10,全排列复杂度(n!)可以忍受。随后把这些排列好的数字放回到原来的空缺位置,统计一下顺序对个数,如果满足要求计数器加1即可。

import copy

permutats = []
def permutation(nums, start):

    if start == len(nums):
        permutats.append(copy.deepcopy(nums))
    else:
        for i in range(start, len(nums)):
            nums[i], nums[start] = nums[start], nums[i]
            permutation(nums, start+1)
            nums[i], nums[start] = nums[start], nums[i]

def calcPairs(nums):
    n = len(nums)
    pairs = 0
    for i in range(n):
        for j in range(i, n):
            if nums[i] < nums[j]:
                pairs += 1
    return pairs


n, k = map(int, input().strip().split())
nums = list(map(int, input().strip().split()))

leftNums = {}
for i in range(1, n+1):
    leftNums[i] = 1
for i in range (len(nums)):
    if nums[i] != 0:
        del leftNums[nums[i]]

leftNums = list(leftNums.keys())

permutation(leftNums, 0)

cnt = 0
for permutat in permutats:
    j = 0
    tmp = copy.deepcopy(nums)
    for i in range(len(nums)):
        if tmp[i] == 0:
            tmp[i] = permutat[j]
            j += 1

    pairs = calcPairs(tmp)
    if pairs == k:
        cnt += 1

print(cnt)

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页