1. import math
  2. import time
  3. def FindRoad(target: [], m: int):
  4. def isvalid(result, target):
  5. temp = result['values']
  6. base = sorted(target)
  7. output = sorted([j - i for i in temp for j in temp if j > i])
  8. for i in range(len(base)):
  9. if output[i] != base[i]:
  10. return False
  11. return True
  12. def isvalid2(num, target):
  13. if num > m:
  14. return False
  15. if num not in target:
  16. return False
  17. return True
  18. def dfs(target, result):
  19. target_dict = {k: 0 for k in target for v in range(len(target))}
  20. # base case
  21. if len(result['values']) == length:
  22. if result['values'][-1] == m:
  23. if isvalid(result, target):
  24. results.append(result)
  25. print(result)
  26. # make progress
  27. else:
  28. for i in range(len(target)):
  29. if target_dict[target[i]] == 1:
  30. # 同一层次, 该元素已经被选择了
  31. continue
  32. # 标记为已选元素
  33. target_dict[target[i]] = 1
  34. b
  35. if result['path'][i] == 1:
  36. target_dict[target[i]] = 0
  37. continue
  38. # 可能的下个元素的值
  39. temp = result['values'][-1] + target[i]
  40. if not isvalid2(temp, target):
  41. continue
  42. result['values'].append(temp)
  43. result['path'][i] = 1
  44. dfs(target, result)
  45. result['path'][i] = 0
  46. result['values'].remove(temp)
  47. length = int(math.sqrt((2 * len(target) + 1))) + 1
  48. # 同一层次只做一次相同选择
  49. results = []
  50. result = {
  51. 'values': [],
  52. 'path': [0 for i in range(len(target))]
  53. }
  54. result['values'].append(0)
  55. dfs(target, result)
  56. nums = [3, 3, 3, 4, 5, 5, 5, 6, 7, 8, 10, 1, 2, 2, 2]
  57. nums = [1, 2, 2, 2, 3, 3, 3, 3, 4, 5, 5, 5, 6, 7, 8, 8, 10, 10, 11, 12, 13, 13, 15, 15, 16, 18, 18, 21]
  58. t1 = time.process_time()
  59. FindRoad(nums, 21)
  60. t2 = time.process_time()
  61. print(t2-t1)
  62. #

总结

  • 横向的剪枝函数
  • 纵向维护路径