试题 算法训练 数字游戏【Python】

试题 算法训练 数字游戏【Python】,第1张

试题 算法训练 数字游戏【Python】

题目:

第一个想法,求出1~n的全排列,按字典序排列,然后从头依次对排列进行 *** 作,得出结果在和sum对比,找出第一个符合要求的序列
结果这样做会超时,只有四十分

all_s = []  # 存储所有序列
def perm(h, r):  # 求所有的序列
    global all_s, lst
    if h >= r:
        all_s.append(lst.copy())
        return
    for i in range(h, r):
        lst[i], lst[h] = lst[h], lst[i]
        perm(h+1, r)
        lst[i], lst[h] = lst[h], lst[i]

n, m = map(int, input().split())
lst = [x for x in range(1, n+1)]
perm(0, n)
all_s.sort()  # 按字典序对所有排列进行排序
# print(all_s)

for i in all_s:
    l = len(i)
    temp = i.copy()
    while l:  # 按题目要求求和
        for j in range(0, l-1):
            i[j] = i[j] + i[j+1]
        l -= 1
    if i[0] == m:  # 如果符合要求就输出序列,并退出循环
        for p in temp: print(p, end=" ")
        break

第二个想法,通过观察序列中每个数字被加的次数,可以发现每个数字被加的次数和n-1的所有组合数有关,就拿样例来说

3 1 2 4
4 3 6(1 ,2 ,2 ,1)
7 9(1 , 3 , 3 , 1)= (C30 , C31 , C32 , C33)
16

所以我们可以先求出n-1的所有组合数,然后对每个组合数枚举对应位置的数字

def COMB(x):  # 动态规划求组合数,也可以用python自带的函数求,math.comb
    lst = [[1 for _ in range(x+1)] for _ in range(x+1)]
    for i in range(2, x+1):
        for j in range(1, i):
            lst[i][j] = lst[i-1][j] + lst[i-1][j-1]
    return lst[x]
def solution(n, m, lst, vis, p, temp, re):
    if p == n:
        if temp == m:
            print(str(re).strip('[]').replace(',', ''))
            vis[0] = 1  # 标记,代表已经找到答案,第一个输出的找到的排列就是答案
            return 0
    if not vis[0]:  # 当标记为1时,代表当前已经输出了最优答案,不需要在继续找了
        for i in range(1, n+1):
            if vis[i] == 0:
                re[p] = i  # 记录当前位置数字
                vis[i] = 1  # 标记这个数字用过了
                if temp+re[p]*lst[p] <= m:  # 约束条件,当和大于m时,是无效的解,没有这个约束条件只有90分
                    solution(n, m, lst, vis, p+1, temp+re[p]*lst[p], re)
                vis[i] = 0  # 将数字恢复到没用过的状态,递归回来的时候让后面的位置可以用这个数字
n, m = map(int, input().split())
re = [0 for _ in range(n)]  # 记录排列
lst = COMB(n-1)  # 存储n-1的所有组合数
# print(lst)
vis = [0 for _ in range(n+1)]  # 标记数组,防止排列中数字重复
solution(n, m, lst, vis, 0, 0,  re)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5658631.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存