work1 work4 work5 work12

main
lensfrex 6 months ago
parent 9ca75884fc
commit 14c8770633
Signed by: lensfrex
GPG Key ID: B1E395B3C6CA0356
  1. 35
      python/cap4/test.py
  2. 49
      python/cap4/work1.py
  3. 27
      python/cap4/work12.py
  4. 19
      python/cap4/work4.py
  5. 50
      python/cap4/work5.py

@ -0,0 +1,35 @@
n = 8
def generateBoard():
board = list()
for i in range(n):
row[queens[i]] = "Q"
board.append("".join(row))
row[queens[i]] = "."
return board
def backtrack(row: int):
if row == n:
board = generateBoard()
solutions.append(board)
else:
for i in range(n):
if i in columns or row - i in diagonal1 or row + i in diagonal2:
continue
queens[row] = i
columns.add(i)
diagonal1.add(row - i)
diagonal2.add(row + i)
backtrack(row + 1)
columns.remove(i)
diagonal1.remove(row - i)
diagonal2.remove(row + i)
solutions = list()
queens = [-1] * n
columns = set()
diagonal1 = set()
diagonal2 = set()
row = ["."] * n
backtrack(0)
print(solutions)

@ -0,0 +1,49 @@
# work1. 01背包问题
# 设 dp[i][w] 表示在背包容量为 w 时,前 i 个物品能够达到的最大总价值。
# 状态转移方程:
# 对于第 i 个物品,存在两种情况:
# 如果第 i 个物品的重量大于当前背包容量 w,则无法放入背包,此时 dp[i][w] 等于 dp[i-1][w],即不放入该物品。
# 如果第 i 个物品的重量小于等于当前背包容量 w,则考虑放入或不放入背包两种情况,取其中价值更大的情况。
# 如果放入第 i 个物品,则总价值为 values[i] + dp[i-1][w-weights[i]]。
# 如果不放入第 i 个物品,则总价值为 dp[i-1][w]。
# 综合考虑以上两种情况,dp[i][w] 的值为这两种情况中的较大值。
# 初始化:
# 当没有物品可选时,背包能够达到的最大总价值为0,即 dp[0][w] = 0,其中 w 取值为0到背包容量 capacity。
# 填充数组:
# 使用两层循环填充 dp 数组,外层循环遍历物品,内层循环遍历背包容量,根据状态转移方程更新 dp[i][w] 的值。
# 回溯:
# 根据 dp 数组中存储的最优解,找出放入的是哪些物品。
# 返回结果:
def knapsack(weights: list[int], values: list[int], capacity: int) -> int:
n = len(weights)
# 创建一个二维数组来存储子问题的解
dp = [[0] * (capacity + 1) for _ in range(n + 1)]
# 填充dp数组
for i in range(1, n + 1):
for w in range(1, capacity + 1):
# 如果当前物品的重量大于背包容量,则不能放入背包
if weights[i - 1] > w:
dp[i][w] = dp[i - 1][w]
else:
# 考虑放入或不放入当前物品,选择其中价值更大的方案
dp[i][w] = max(dp[i - 1][w], values[i - 1] + dp[i - 1][w - weights[i - 1]])
# 找出放入背包的物品
selectedItems = []
i, w = n, capacity
while i > 0 and w > 0:
if dp[i][w] != dp[i - 1][w]:
selectedItems.append(i - 1)
w -= weights[i - 1]
i -= 1
return dp[n][capacity], selectedItems
# 测试
weights = [10, 20, 30, 40, 50]
values = [50, 120, 150, 210, 240]
capacity = 50
max_value, selected_items = knapsack(weights, values, capacity)
print("最大价值:", max_value)
print("选择的物品索引:", selected_items)

@ -0,0 +1,27 @@
# work12
# 有一个由数字1,2,…,9组成的数字串,长度不超过200,
# 问如何将M(1≤M≤20)个加号插入这个数字串中,使得所形成的算法表达式的值最小。
def get_num(nums: list[int]) -> int:
result = 0
for num in list:
result = result*10 + num
return result
dp = []
def solve(nums: list, p: int, x: int) -> int:
if dp[p][x] != -1:
return dp[p][x]
if x == 0:
dp[p][0] = get_num(nums[0,p])
return dp[p][0]
for i in range(x, p-1, -1):
dp[p][x] = min(dp[p][x], solve(i, x-1)+get_num(nums[i:p]))
return dp[p][x]
result = solve([7,9,8,4,6], 5, 20)
print(result)

@ -0,0 +1,19 @@
# work4 求最大字字段和(同例15的解法,此处为python版本写法)
# o(n)时间复杂度,o(1)空间。
# 一路扫描,currMaxSum为当前位置为止的最大和,当到下一个位置时,判断当前数字num加上currMaxSum是否会导致比当前num还小,
# 如果当前数字num加上currMaxSum是否会导致比当前num还小,则说明最大的和不应从前面开始,而是*至少*应当从当前的数字开始
# 下一步比较结果与当前的最大和哪个大,取更大的作为结果
def findMaxSum(nums: list[int]) -> int:
result = nums[0]
currMaxSum = nums[0]
for i in range(1, len(nums)):
num = nums[i]
currMaxSum = max(currMaxSum+num, num)
result = max(result, currMaxSum)
return result
# test
nums = [-2, 11, -4, -9, 13, -5, 7, -3]
result = findMaxSum(nums)
print("最大子段和:", result)

@ -0,0 +1,50 @@
# work5 八皇后问题
# 在8乘8的国际象棋棋盘上,放8个皇后,皇后可以吃掉与之同行同列以及同一对角线上的其他皇后。
# 为让她们共存,找出所有放置方法。
n = 4
queens = [-1]*n
used_columns = set()
used_left_diagonal = set()
used_right_diagonal = set()
def can_put_queen(row, col):
return (col not in used_columns) and (row-col not in used_right_diagonal) and (row+col not in used_left_diagonal)
def put_queen(row, col):
queens.append((row, col))
used_columns.add(col)
used_right_diagonal.add(row-col)
used_left_diagonal.add(row+col)
def remove_queen(row, col):
queens.remove((row, col))
used_columns.remove(col)
used_right_diagonal.remove(row-col)
used_left_diagonal.remove(row+col)
result = list()
def queen(row: int) -> list[list[str]]:
if row == n:
rowText = ["."] * n
board = list()
for i in range(n):
rowText[queens[i]] = "Q"
board.append("".join(rowText))
rowText[queens[i]] = "."
result.append(board)
for col in range(n):
if not can_put_queen(row, col):
continue
queens[row] = col
put_queen(row, col)
queen(row+1)
remove_queen(row, col)
queen(0)
for board in result:
for row in board:
print(row)
print("------------")
Loading…
Cancel
Save