从最短编辑距离问题到初识动态规划

今天的题目虽然是从最短编辑距离到初识动态规划,但实际上,要解最短编辑距离,还是得从动态规划开始。
摘要由CSDN通过智能技术生成

先说些题外话:

​ 作为一个算法小白,我在领到最短编辑距离这个讲题的时候头就秃了一半,在后面看动态规划的时候剩下一半还不够我秃的👨‍🦲。

​ 今天的题目虽然是从最短编辑距离到初识动态规划,但实际上,要解最短编辑距离,还是得从动态规划开始。

​ 动态规划(Dynamic Programming),是一种用于求解最优问题的算法,相对其他算法(如回溯算法:穷举所有可能,时间复杂度为指数级),动态规划可以显著地降低时间复杂度。但是动态规划并不好学,而且因为某种莫名的力量,是众所周知的难学。主要是因为动态规划“求解问题的过程不太符合人类常规的思维方式”。

在这里插入图片描述

动态规划将问题分为多个决策阶段,每个阶段做一个决策(选择),记录每个阶段做完决策的状态,通过上一个阶段的状态推导出下一个阶段的状态,动态地推演。(划重点)

0-1背包问题

​ 学习动态规划,主要还是多练,~~所以这是一节习题课…~~下面我们先通过一个非常著名的0-1背包问题,认识一下动态规划。

问:

有一个承重为w的背包,可装载的物品共有n个,在重量分别为weight(一个代表不同物品重量的数组)的物品中,可装载的重量最大值是多少?

如:背包可装9kg,5个物品,提供的物品有[2,2,4,6,3]kg

解:

我们将问题分解为物品总个数个阶段,每个阶段决策当前物品是否装入背包,每个阶段状态即当前总重量是否可达。即,挨个选择要不要这个物品。这个过程可以画一张表格来表示,1表示状态可达,0表示状态不可达。

0 1 2 3 4 5 6 7 8 9
w=2 1 0 1 0 0 0 0 0 0 0
w=2 1 0 1 0 1 0 0 0 0 0
w=4 1 0 1 0 1 0 1 0 1 0
w=6 1 0 1 0 1 0 1 0 1 0
w=3 1 0 1 1 1 1 1 1 1 1

这个表格我们称为状态转移表,有了状态转移表,就可以用代码来描述这个表格:

定义数组=>初始化边界值=>推演

// weight:物品重量,n:物品个数,w:背包可承载重量
function knapsack(weight = [2,2,4,6,3], n = 5, w = 9) {
   
  // 定义二维数组
  let state = []
  for(let i = 0; i < n; i++) {
   
    state[i]=[]
  }
  
  // 初始化第一行数据
  state[0][0]=true
  if(weight[0] < w){
   
    state[0][weight[0]] = true
  }

  // 动态规划状态转移
  for(let i = 1; i < n; i++) {
   
    // 决策为不放入背包
    for(let j = 0; j <= w; j++) {
   
      if(state[i-1][j]) state[i][j]=state[i-1][j]
    }
    // 决策为放入背包
    for(let j = 0; j <= w - weight[i]; j++) {
   
      if(state[i-1][j]) state[i][j+weight[i]]=true
    }
  }

  for(let i = w; i >= 0; i--) {
   
    if(state[n-1][i]) return i
  }

  return 0
}

结论:

这串代码的时间复杂度为O(n*w),但是额外申请了一个n*(w+1)的数组。

所以有时候我们说动态规划是拿空间来换时间。

优化:

实际上,这段代码还可以优化成一维数组:

function knapsack2(weight = [2,2,4,6,3], n = 5, w = 9) {
   
  // 定义数组
  let state = []
  // 初始化
  state[0]=true
  if(weight[
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值