回溯法python(迷宮模板)和01揹包問題

2021-10-04 10:54:53 字數 3282 閱讀 6878

1.題目:乙個 n × m的二維陣列 maze 表示乙個迷宮,其中的1表示牆壁,0表示可以走,只能橫著走或豎著走,不能斜著走,找出從左上角到右下角的最短路線。入口點為[0,0],既第一空格是可以走的。

回溯法:

# 走迷宮

def move(i, j):

global path

# 當前點變為1,表示已經走過,避免迴圈繞圈走不出去

maze[i][j] = 1

# 如果已經走到了出口,即右下角,判斷是不是最短路徑

if i == n - 1 and j == m - 1:

if len(path) == 0 or len(temp_path) < len(path):

path =

path.extend(temp_path)

# 向下走

if 0 <= i + 1 < n and not maze[i + 1][j]:

move(i + 1, j)

# 向右走

if 0 <= j + 1 < m and not maze[i][j + 1]:

move(i, j + 1)

# 向上走

if 0 <= i - 1 < n and not maze[i - 1][j]:

move(i - 1, j)

# 向左走

if 0 <= j - 1 < m and not maze[i][j - 1]:

move(i, j - 1)

# 如果上下左右都走不通或者已經走到出口了,退回上一步,恢復現場

temp_path.pop()

maze[i][j] = 0

while true:

try:

# 輸入迷宮大小

n, m = map(int, input().split())

maze =

path =

temp_path =

# 輸入迷宮地圖

for _ in range(n):

# 走迷宮

move(0, 0)

# 列印路徑

for p in path:

print('(' + str(p[0]) + ',' + str(p[1]) + ')')

except:

break

2.01揹包問題**

def knapsack(p, w, v):

n = len(p)

lists,arr = ,[[0] * (v + 1) for _ in range(n + 1)]

for i in range(1, n + 1):

for j in range(1, v + 1):

if w[i - 1] <= j: # 如果當前物品的體積不超過揹包的容量,p[i-1]當前物品的價值,w[i-1]當前物品的體積

arr[i][j] = max(arr[i - 1][j], p[i - 1] + arr[i - 1][j - w[i - 1]])

else: #如果當前物品的體積超過揹包的容量

arr[i][j] = arr[i - 1][j]

print(arr[i][j])

remain = v

for i in range(n, 0, -1):

if arr[i][remain] > arr[i - 1][remain]:

remain -= w[i - 1] # 容積減去已經找到的物品,再次尋找

return arr[-1][-1], lists

if __name__ == '__main__':

p = [700 ,500, 800 ,600 ,520] # 物品的價值

w = [3, 2, 9, 4, 3] # 物品佔的體積

v = 8 # 揹包的容量

print(knapsack(p, w, v))

3.快速排序

def partition(arr, low, high):

i = (low - 1) # 最小元素索引

pivot = arr[high]

for j in range(low, high):

# 當前元素小於或等於 pivot

if arr[j] <= pivot:

i = i + 1

arr[i], arr[j] = arr[j], arr[i]

arr[i + 1], arr[high] = arr[high], arr[i + 1]

return (i + 1)

# 快速排序函式

def quicksort(arr, low, high):

if low < high:

pi = partition(arr, low, high)

quicksort(arr, low, pi - 1)

quicksort(arr, pi + 1, high)

if __name__ == '__main__':

arr = [10, 7, 8, 9, 1, 5]

n = len(arr)

quicksort(arr, 0, n - 1)

print("排序後的陣列:")

for i in range(n):

print("%d" % arr[i])

4.並歸排序

# 歸併排序

def merge_sort(ary):

if len(ary) <= 1:

return ary

median = int(len(ary)/2) # 二分分解

left = merge_sort(ary[:median])

right = merge_sort(ary[median:])

return merge(left, right) # 合併陣列

def merge(left, right):

'''合併操作,

將兩個有序陣列left和right合併成乙個大的有序陣列'''

res =

i = j = k = 0

while(i < len(left) and j < len(right)):

if left[i] < right[j]:

i += 1

else:

j += 1

res = res + left[i:] + right[j:]

return res

回溯法 迷宮問題

1.首先我們需要自定義乙個迷宮 左上角為入口,右下角為出口,0為路,1為牆 用二維陣列儲存 2.我們在走迷宮之前,首先要確立乙個走的順序,即貪心準則,我們首先試探的方向應該是下,然後是右,上,左 為了確保每乙個格仔都有上下左右,我們需要給我們的迷宮加上一圈牆8 8,變成10 10 3.當我們在乙個格...

迷宮問題 回溯法

描述 給乙個20 20的迷宮 起點座標和終點座標,問從起點是否能到達終點。輸入 多個測例。輸入的第一行是乙個整數n,表示測例的個數。接下來是n個測例,每個測例佔21行,第一行四個整數x1,y1,x2,y2是起止點的位置 座標從零開始 x1,y1 是起點,x2,y2 是終點。下面20行每行20個字元,...

回溯法模板

void run 當前狀態 for int i 算符最小值 i 算符最大值 i 這只是乙個大致的輪廓,需要根據試題要求,做適當的調整。例如,對非最優性問題,可略去當前狀態是否為最佳目標狀態和擴充套件出的子狀態是否滿足最優性要求的判斷,若是求最長路徑,可略去邊界條件的判斷,等等,但是在使用回溯法解題時...