算法基础学习——动态规划

核心思想

  • 自底向上,对应于递归的自上而下
  • 状态(数值)转移(一步步)方程(求解)
  • 要进行空间优化(减少重复求解次数)
  • 当初始状态给定时,用逆推比较方便;当终止状态给定时,用顺推比较方便

如果说贪心是局部最优,动态规划就是全局最优

通用解法

  • 将问题拆分为子问题
    • 什么是子问题:子问题与原问题形式相同或相似,但规模更小
    • 限制:子问题求出的解要记录(选择最优情况),优化子问题求解次数
    • 求解:使用状态转移方程
  • 确定状态
    • 什么是状态:和子问题相关变量的一组取值(为了方便计算存储的数据)
    • 怎么存储:是选择一维还是二维数组还是其他数据结构呢
  • 分析边界状态
    • 状态数组的边界部分(推断已知数据填起始值)
  • 确定状态转移方程
    • 使用已知的状态(已经存储的数据)求出未知状态(待求解数据)
    • 转移过程:类似于递归
    • 类似时刻的概念,t0 时刻的值 和 t1 时刻的值
  • 根据方程遍历
    矩阵路径问题

状态转移方程 tips

  • 每次只消除一个变量,来寻找状态转移方程
  • 若无明显确定的初始状态,可全部初始化为某个一般值,并按照某种排序顺序进行递归遍历更新 ( 感觉像数学题,不会就填 012 )
  • 若无法形成递推关系,则考虑状态里的变量是不是少了

使用场景

不要求列出问题的所有解,只要求计算解的数目或找出其中一个最优解

看到动态规划,我的第一反应是《运筹学》中的动态规划,然而在众多算法讲解下我关注矛盾点逐渐偏移,还好拽回来了。这俩玩意是一个东西,细节略有不同,相关文章3也讲了这个问题。

运筹学中,如果遇到在某个限制条件下求最优解的问题(如背包问题),则可以使用动态规划。基本概念有6个:

  • 阶段(问题划分为多个相互联系的时刻)
  • 状态(每个阶段问题的状况)
  • 决策(当过程处于某阶段的某状态时,可以做出的不同决定,会影响下一阶段状态)
  • 策略(决策按顺序排列的集合,要寻找最优策略)
  • 状态转移方程(一个状态到另一个状态的演变过程)
  • 指标函数和最优值函数(指标函数:衡量过程优劣的数量指标,如各阶段指标的或者乘积,最优值函数:指标函数的最优值,minmax

其强调了策略的概念,结合该点能更快的识别动态规划问题。

最长递增子序列

以 i 结尾的最长递增子序列元素个数,应当是上一个比 i 小的结尾子序列元素个数的+1,子序列至少有1个元素。
arr: [1,3,5,9,2,4]
dp: [1,2,3,4,2,3]

let inputs = [5,2,4,9,2,3]

function computeMax(arr){
    let ans = 0

    let dp = new Array(arr.length)
    dp.fill(1)

    for (let i = 0; i < arr.length; i ++) {
        for (let j = 0; j < i; j ++) {
            if (arr[i] > arr[j]) 
                dp[i] = Math.max(dp[i], dp[j] + 1);
    
            console.log(i,j,dp)   
        }
    }
    for (let i = 0; i < dp.length; i ++) {
        ans = Math.max(ans, dp[i]);
    }
    return ans
}

console.log(computeMax(inputs))
1 0 [ 1, 1, 1, 1, 1, 1 ]
2 0 [ 1, 1, 1, 1, 1, 1 ]
2 1 [ 1, 1, 2, 1, 1, 1 ]
3 0 [ 1, 1, 2, 2, 1, 1 ]
3 1 [ 1, 1, 2, 2, 1, 1 ]
3 2 [ 1, 1, 2, 3, 1, 1 ]
4 0 [ 1, 1, 2, 3, 1, 1 ]
4 1 [ 1, 1, 2, 3, 1, 1 ]
4 2 [ 1, 1, 2, 3, 1, 1 ]
4 3 [ 1, 1, 2, 3, 1, 1 ]
5 0 [ 1, 1, 2, 3, 1, 1 ]
5 1 [ 1, 1, 2, 3, 1, 2 ]
5 2 [ 1, 1, 2, 3, 1, 2 ]
5 3 [ 1, 1, 2, 3, 1, 2 ]
5 4 [ 1, 1, 2, 3, 1, 2 ]
3

相关文章

  1. 【算法训练营学习笔记-Week05】动态规划其实“名不符实”,动态递推更容易理解
  2. 算法基础 - 枚举/递归/动归/深广搜/二分/贪心
  3. 五大算法之一-动态规划(从《运筹学》和《算法导论》两个角度分析)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值