chapter_dynamic_programming/dp_solution_pipeline/ #589
Replies: 28 comments 37 replies
-
for (int i = 1; i < n; i++) { |
Beta Was this translation helpful? Give feedback.
-
太厉害了!!!!!,义父,请受孩儿一拜 |
Beta Was this translation helpful? Give feedback.
-
总结: 一个小小疑惑: 如果我理解的没错的话,这里应该是指: |
Beta Was this translation helpful? Give feedback.
-
这个空间优化实在太妙了。 每一行的遍历开始的时候:dp[0] 是新一行的值,而dp[i] 是上一行的值,由此将其全部推导为当前行的值 |
Beta Was this translation helpful? Give feedback.
-
图 14-16 的第2列貌似错了 |
Beta Was this translation helpful? Give feedback.
-
请教!DP问题如果可以列出DP表,看起来就包含着问题的解,那我们实际解决问题的时候比较确定这是一题符合DP问题特点的题目时,是否可以直接考虑使用DP表直接写出最终答案,而不需要考虑暴力搜索等其他解?因为好像有时候反而不容易想到要如何暴力搜索,而是很强烈的感觉这题用dp表可以做。 |
Beta Was this translation helpful? Give feedback.
-
您好,我问一下:for i in range(1, n): |
Beta Was this translation helpful? Give feedback.
-
如果右上的5和2都换成1,这个每次选最小的,出来的路线就不不对了,这样直接走两条直角边总和才10 |
Beta Was this translation helpful? Give feedback.
-
文中的先观察问题是否适合使用回溯(穷举)解决这句话感觉可以调整成是否适合使用回溯(自上向下穷举)解决,因为我一开始用自下向上的回溯发现没法用记忆搜索优化,导致推导不出后面的问题,哈哈,可能是我太菜了 |
Beta Was this translation helpful? Give feedback.
-
复杂的算法能从浅入深,作者的功力太强了,算法这种就是做出来容易讲出来让别人理解难 |
Beta Was this translation helpful? Give feedback.
-
k神能省则省,这思路太牛了 |
Beta Was this translation helpful? Give feedback.
-
给大佬提一个可能不合理的小建议,如果在代码之前写一下输入和输出是什么,可能会更容易让凡人理解。 |
Beta Was this translation helpful? Give feedback.
-
import torch
cost = torch.tensor([[1,3,1,5],
[2,2,4,2],
[5,3,2,1],
[4,3,5,2]])
dp = torch.ones_like(cost)*torch.inf
dp[0,0] = 1
for i in range(4):
for j in range(4):
last_i = i-1
last_j = j-1
if last_i>=0 and last_j>=0:
dp[i,j] = torch.min(dp[last_i,j], dp[i,last_j]) + cost[i,j]
elif last_i>=0 and last_j<0:
dp[i, j] = dp[last_i, j] + cost[i, j]
elif last_i<0 and last_j>=0:
dp[i, j] = dp[i, last_j] + cost[i, j]
else:
pass
print(dp[3,3]) 终于好像有get到一点点动态规划了,人生第一个动态规划的代码! |
Beta Was this translation helpful? Give feedback.
-
感觉动态规划和强化学习好像啊。 强化学习里面也有初始状态、终止状态、马尔科夫性、状态转移方程。 或者是否能说DP和RL都是用来解决序列决策问题的方法,不过DP要求问题的状态转移方程已知;而RL则通过与环境互动学习各个状态的最优决策,不需要状态转移方程。 另外有一个问题,DP问题中,如何对状态转移进行剪枝呢?换句话说,如何对设计合适的状态转移方法,尽可能少地探索状态以到达我们的目标状态? |
Beta Was this translation helpful? Give feedback.
-
Hi,我有些疑问。如果我有个4*4的表格
如果我要求从左上角到(2,2)的最小路径和,根据这个算法得到的结果是4,没有问题。 |
Beta Was this translation helpful? Give feedback.
-
回溯算法不是需要做出选择与回退选择吗,看代码里没有体现呢 |
Beta Was this translation helpful? Give feedback.
-
这小节的空间优化还是有点绕。很巧妙。 |
Beta Was this translation helpful? Give feedback.
-
// 若为左上角单元格,则终止搜索 |
Beta Was this translation helpful? Give feedback.
-
a=[[1,1,2,3],
[10,1,0,0]
[1,1,2,1]] k神你好,对于其中dp[2,0]的值按照初始化为12,但是按照最小代价来看,不应该是1+1+1+1+1为5 |
Beta Was this translation helpful? Give feedback.
-
怎么把最短路径索引也记录下来? |
Beta Was this translation helpful? Give feedback.
-
如果这个图尺寸变大,路径方向可能还会包含向上或者向左,涉及到新代价值计算先后的问题,是不是就不适用动态规划了 |
Beta Was this translation helpful? Give feedback.
-
尝试用前一章节学的回溯代码来暴力解决这个问题: 除了返回最小路径和以外,同时返回所有最小路径和的路径。 grid = [[1, 2, 1, 5], [2, 2, 4, 2], [5, 3, 2, 1], [4, 3, 5, 2]]
row=len(grid)
col=len(grid[0])
def backtrack(#python
state:int,
path:list[list[int]],
i,
j,
choices:list[int],
grid:list[list[int]],
result:list[int],
path_result:list[list[list[int]]]
):
#state表示当前位置的路径和,path用来记录当前路径,i,j是当前位置的坐标
#choices=[0,1],0表示向下走,1表示向右走
#result是长度为1的列表,用来保存最小的state,path_result用来保存最小state对应的path
#row,col表示grid的总行数和总列数,row,col,grid都是是全局变量
#解的判断:是否已经走到最右下角
if i == row-1 and j == col-1:
#result为空,说明是第一条路径,无论如何都记录
if not result:
result.append(state)
path_result.append(list(path))
#只要state比当前的result的更小,结果就更新。
elif result[0]>state:
result[0]=state
#因为新的state更小,此前保存的path都无效了,需要清空path_result
path_result.clear()
path_result.append(list(path))
#如果是重复的最小路径和,只添加这一条path进来
elif result[0]==state:
path_result.append(list(path))
return
for choice in choices:
if choice == 0:#=0表示向下走
if i == row-1:#剪枝
continue#已经到底,不往下走了
#更新状态
i+=1
state+=grid[i][j]
path.append([i,j])
backtrack(state,path,i,j,choices,grid,result,path_result)
#回撤
state-=grid[i][j]
path.pop()
i-=1
if choice == 1:#=1表示向右走
if j == col-1:
continue
j+=1
state+=grid[i][j]
path.append([i,j])
backtrack(state,path,i,j,choices,grid,result,path_result)
state-=grid[i][j]
path.pop()
j-=1
def min_path_sum_backtrack(grid:list[list[int]]):
state=grid[0][0]
result=[]
path=[[0,0]]
path_result=[]
backtrack(state,path,0,0,[0,1],grid,result,path_result)
return result[0],path_result
sum,path_list=min_path_sum_backtrack(grid)
#打印结果
print(f'最小路径和:{sum}')
for i in range(len(path_list)):
print(f'\n最小路径{i+1}:')
print(path_list[i]) |
Beta Was this translation helpful? Give feedback.
-
请教,空间优化后的代码的dp表容量是只有4吗,也就意味着程序运行结束后只有最后一行的最小路径和? |
Beta Was this translation helpful? Give feedback.
-
这里面第一个的暴力搜索算法是属于回溯算法吗? |
Beta Was this translation helpful? Give feedback.
-
dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]; 空间优化,思考了一会才理解,min里面的dp[j-1]是当前位置左边的格子的值,dp[j]是刚刚计算的上一行的对应位置的的值,所以刚好对应左边和上边两个元素,计算之后dp[j]就被当前位置的值替代,用来进行下一次的计算,巧妙! |
Beta Was this translation helpful? Give feedback.
-
在记忆化搜索中假如mem数组一开始全是-1,首先求解dp[i][j] ,i和j均很大,那么实际上这种解法就是暴力搜索,因为搜索是从顶至底的,所以if (mem[i][j] != -1) return mem[i][j] 并没有发挥作用 |
Beta Was this translation helpful? Give feedback.
-
C++版本代码中使用「min(left, up) != INT_MAX」是必要的吗?up和left应该不能同时返回INT_MAX吧? |
Beta Was this translation helpful? Give feedback.
-
LeetCode 最小路径和 传送门: https://leetcode.cn/problems/minimum-path-sum/description/ |
Beta Was this translation helpful? Give feedback.
-
chapter_dynamic_programming/dp_solution_pipeline/
动画图解、一键运行的数据结构与算法教程
https://www.hello-algo.com/chapter_dynamic_programming/dp_solution_pipeline/
Beta Was this translation helpful? Give feedback.
All reactions