算法思想-动态规划

我所理解的动态规划,其本质是对递归的优化。所以一般需要先找出其递归方式,才能进一步地优化。但是,只要刷题数量达到了一定程度,就会隐约感觉到有一个解题模板,只需要按照这个模板去比对各种条件就可以解题。

动态规划核心三问题

  1. 状态,动态规划都会使用到辅助数组来记录问题的解,这些数组的下标具有重要作用,一定要弄明白下标究竟表示哪种状态的解。
  2. 转移方程,其本质是递归方程
  3. 初始化,不同的问题要采用不同的初始化方式
  1. 状态
    辅助数组一般有三种:一维数组,二维数组和三维数组。首先要明确使用几维的辅助数组作为解的记录,然后要弄清楚数组的下标表示什么,尤其是二维数组的下标,其含义可以千变万化。

1.单序列问题,采用一维数组
2.一维的代价,采用二维数组
3.二维的代价,采用三维数组

  1. 转移方程
    转移方程与状态的联系非常紧密,

解题模板

1.1 单序列问题

单序列问题指的是使用一个一维数组(假设该数组名为dp)作为问题解(假设原问题的数组名为input)的记录,那么dp[i]的状态就一般表示为以当前元素作为结尾时的最优解。其状态转移方程分为以下几种情况:
dp[i]只与dp[i-1]有关,即该状态只与前一个状态相关
dp[i]与dp[0],dp[1]…dp[i-1]有关或者部分有关(很多时候可能是dp[i-j]和dp[j]),即该状态需要搜索前面全部已知状态,然后选取一个最优值

1.2 二维和三维辅助数组

所谓一维的费用,指的是每个物品具有一种费用,选择这个物品时只需要付出一种费用,譬如硬币问题,

所谓二维的费用,指的是每个物品具有两种不同的费用,选择这个物品时必须同时付出两种费用,譬如01组合问题,费用增加了一维,只需要状态也增加一维,设dp[i,v,u]表示前i个物品付出两种费用分别为v和u时可获得的最大价值。

解题流程

1.确认这是一个什么类型的问题,是单序列问题,还是背包问题
2.如果是单序列问题

2.1当前状态的状态转移方程是怎样的:是只与前一个状态有关,还是要在前面的所有状态之间挑选一个最优值
2.2初始化状态是怎样的:当只有一个元素的时候,解是怎样的

3.如果是背包问题

单序列问题

针对单序列问题,我采用的解题流程包括以下几步:

背包问题

针对背包问题,我所采用的解题流程包括以下几步:
1.这是一个什么类型的背包问题:

0/1背包 (每个物品只能选取一次) - 逆序循环
完全背包(每个物品可以重复选取) - 顺序循环
多重背包 - 拆分物品

2.初始化该怎么设置

求背包价值的最大值,最小值

要求恰好装满背包 -
初始化时除了dp[0]为0,其他dp[1…v]均设置为负无穷,这样就可以保证最终得到的dp[v]是一种恰好装满背包的最优解
没有要求恰好装满背包,初始化时将dp[0…v]全部设置为0 求数量的最大值,最小值

最小值,dp[0]设置为0,dp[1…v]设置为v+1
最大值,dp[0…v]设置为0 题目类型归类 组合问题-硬币问题

转发:https://kylinlingh.github.io/2018/07/05/algo-dynamic programming/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值