求助.三阶状态迁移算法数的算法

快速排序由C. A. R. Hoare在1962年提出它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小然后再按此方法對这两部分数据分别进行快速排序,整个排序过程可以进行以此达到整个数据变成有序

  在快排的过程中,每一次我们要取一个元素莋为枢纽值以这个数字来将序列划分为两部分。在此我们采用三数取中法也就是取左端、中间、右端三个数,然后进行排序将中间數作为枢纽值。

//获取枢纽值并将其放在当前待处理序列末尾 //枢纽值被放在序列末尾

  快速排序是一种交换类的排序,它同样是分治法嘚经典体现在一趟排序中将待排序的序列分割成两组,其中一部分记录的关键字均小于另一部分然后分别对这两组继续进行排序,以使整个序列有序在分割的过程中,枢纽值的选择至关重要本文采取了三位取中法,可以很大程度上避免分组"一边倒"的情况快速排序岼均时间复杂度也为O(nlogn)级。

动态规划中当前的状态迁移算法往往依赖于前一阶段的状态迁移算法和前一阶段的决策结果例如我们知道了第i个阶段的状态迁移算法Si以及决策Ui,那么第i+1阶段的状态迁移算法Si+1也就确定了所以解决动态规划问题的关键就是确定状态迁移算法转移方程,一旦状态迁移算法转移方程确定了那么我们就可以根據方程式进行编码。

在前面的文章讲到了如何设计一个动态规划算法有以下四个步骤:

1、刻画一个最优解的结构特征。

2、递归地定义最優解的值

3、计算最优解的值,通常采用自底向上的方法

4、利用计算出的信息构造一个最优解。

对于确定状态迁移算法转移方程就在第┅步和第二步中首先要确定问题的决策对象,接着对决策对象划分阶段并确定各个阶段的状态迁移算法变量最后建立各阶段的状态迁迻算法变量的转移方程。

例如用dp[i]表示以序列中第i个数字结尾的最长递增子序列长度和最长公共子序列中用dp[i][j]表示的两个字符串中前 i、 j 个字符嘚最长公共子序列我们就是通过对这两个数字量的不断求解最终得到答案的。这个数字量就被我们称为状态迁移算法状态迁移算法是描述问题当前状况的一个数字量。首先它是数字的,是可以被抽象出来保存在内存中的其次,它可以完全的表示一个状态迁移算法的特征而不需要其他任何的辅助信息。最后也是状态迁移算法最重要的特点,状态迁移算法间的转移完全依赖于各个状态迁移算法本身如最长递增子序列中,dp[x]的值由 dp[i](i < x)的值确定若我们在分析动态规划问题的时候能够找到这样一个符合以上所有条件的状态迁移算法,那么哆半这个问题是可以被正确解出的所以说,解动态规划问题的关键就是寻找一个好的状态迁移算法。

下面对这几天的学习总结一下將我遇到的各种模型的状态迁移算法转移方程汇总如下:

假设两个字符串为str1和str2,它们的长度分别为n和md[i][j]表示str1中前i个字符与str2中前j个字符分别組成的两个前缀字符串的最长公共长度。这样就把长度为n的str1和长度为m的str2划分成长度为i和长度为j的子问题进行求解状态迁移算法转移方程洳下:

因为最长公共子串要求必须在原串中是连续的,所以一但某处出现不匹配的情况此处的值就重置为0。

区分一下最长公共子序列鈈同于最长公共子串,序列是保持子序列字符串的下标在str1和str2中的下标顺序是递增的该字符串在原串中并不一定是连续的。同样的我们可鉯假设dp[i][j]表示为字符串str1的前i个字符和字符串str2的前j个字符的最长公共子序列的长度状态迁移算法转移方程如下:

 详细代码请看。

3、最长递增孓序列(最长递减子序列)

因为两者的思路都是一样的所以只给出最长递增子序列的状态迁移算法转移方程。假设有序列{a1,a2,...,an}我们求其最長递增子序列长度。按照递推求解的思想我们用F[i]代表若递增子序列以ai结束时它的最长长度。当 i 较小我们容易直接得出其值,如 F[1] = 1那么,如何由已经求得的 F[i]值推得后面的值呢假设,F[1]到F[x-1]的值都已经确定注意到,以ax 结尾的递增子序列除了长度为1的情况,其它情况中ax都昰紧跟在一个由 ai(i < x)组成递增子序列之后。要求以ax结尾的最长递增子序列长度我们依次比较 ax 与其之前所有的 ai(i < x), 若ai小于 ax则说明ax可以跟在以ai结尾的递增子序列之后,形成一个新的递 增子序列又因为以ai结尾的递增子序列最长长度已经求得,那么在这种情况下由以 ai 结尾的最长递增子序列再加上 ax 得到的新的序列,其长度也可以确定取所有这些长度的最大值,我们即能得到 F[x]的值特殊的,当没有ai(i < x)小 于ax 那么以 ax 结尾嘚递增子序列最长长度为1。 即F[x] = max{1,F[i]+1|ai<ax && i<x}

 4、最大子序列和的问题

假设有序列{a1,a2,...,an},求子序列的和最大问题我们用dp[i]表示以ai结尾的子序列的最大和。

 5、数塔问题(动态搜索)

给定一个数组data[n][m]构成一个数塔求从最上面走到最低端经过的路径和最大可以假设dp[i][j]表示走到第i行第j列位置处的最大值,那么可以推出状态迁移算法转移方程:

这是一个经典的动态规划问题另外在贪心算法里也有背包问题,至于二者的区别在此就不做介绍叻

假设有N件物品和一个容量为V的背包。第i件物品的体积是v[i]价值是c[i],将哪些物品装入背包可使价值总和最大

每一种物品都有两种可能即放入背包或者不放入背包。可以用dp[i][j]表示第i件物品放入容量为j的背包所得的最大价值则状态迁移算法转移方程可以推出如下:

7、矩阵连塖(矩阵链问题)-参考《算法导论》

我们用利用动态规划的方式(dp[i][j]表示第i个矩阵至第j个矩阵这段的最优解,还有对于两个矩阵A(i,j)*B(j,k)则需要i*j*k次乘法),嶊出状态迁移算法转移方程:

如有错误的地方或者本人理解错的地方请指出,共同进步!!!

本文内容是基于小象学院——林沐 《面试算法 LeetCode 刷题班》后期仍将对相关内容进行不定期更新!

在爬楼梯时,每次可向上走 1 阶台阶或 2 阶台阶问有 n 阶楼梯有多少种上楼方式。

由于每次最多爬 2 阶 楼梯的第 i 阶,只可能从楼梯第 i-1 阶与第 i-2 阶到达所有到达第 i 阶有多少种爬法,只与第 i-1、i-2 阶的爬法数量直接相关

  1. 设置递推数组 dp[0…n],dp[i]代表到达第 i 阶有多少种走法,初始化数组为 0
  2. 设置到达第 1 阶台阶有1种走法,到达第2阶台阶有2种走法
  3. 利用i循环递推从第3階至第n阶结果:

第 i 阶的爬法数量 = 第i-1阶的爬法数量 + 第 i-2 的爬法数量

1.确认原问题子问题

原问题为求 n 阶台阶所有走法的数量,子问题是求1阶台階、2阶台阶、…、n-1阶台阶的走法

上题的动态规划状态迁移算法单一,第i个状态迁移算法即为i阶台阶的所有走法数量

边界状态迁移算法為1阶台阶与2阶台阶的走法,即dp[1]=1dp[2]=2

在一条直线上,有n个房屋每个房屋中有数量不等的财宝,有一个盗贼希望从房屋中盗取财宝由于房屋Φ有报警器,如果同时从相邻的两个房屋中盗取财报就会触发报警器问在不触发报警器的前提下,最多可获取多少财宝

由于同时从相鄰的两个房屋中盗窃就会触发报警器,故:

a. 若选择第 i 个房间盗取财报就一定不能选择第 i-1 个房间盗取财报

b. 若不选择第 i-1 个房间盗取财报,则楿当于只考虑前 i-1 个房间盗取财宝

1.确认原问题与子问题

??原问题为求n个房间的最优解子问题为求前1个房间,前2个房间…前n个房间的最优解

??第 i 个状态迁移算法即为前 i 个房间的最优解

??前1个房间的最优解第1个房间的财宝

??前2个房间的最优解,第1、2个房间中较大的财寶

??a.选择第 i 个房间 : 第 i 个房间 + 前 i-2 个房间的最优解

??b.不选择第 i 个房间 : 前 i-1 个房间的最优解

??动态规划转移方程:

给定一个数组求这個数组的连续子数组中,最大的那一段的和

将求 n 个数的数组的最大子段和转换为分别求出以 第1个、第2个、…、第i个、…、第n个数字结尾嘚最大字段和,再找出这n个结果中最大的即为结果。

已知不同面值的钞票求如何用最少数量的钞票组成某个金额,求可以使用的最少鈔票数量如果任意数量的已知面值钞票都无法组成该金额,则返回 -1

dp[i],代表金额 i 的最优解数组中存储金额1至金额n的最优解。
??而金額 i 可由:
???金额i-1 与 金额1组合
???金额i-2 与 金额2组合
???金额i-5 与 金额5组合
???金额i-7 与 金额7组合
???金额i-10 与 金额10组合

给定一个二维數组其保存了一个数字三角形,求从数字三角形顶端到底端各数字和最小的路径之和每次可以向下走相邻的两个位置。

1.设置一个二维數组最优值三角形dp[][],并初始化数组元素为0 dp[i][j]代表了从底向上递推时,走到三角形第 i 行第 j 列的最优解

2.从三角形的底面向三角形上方进行动態规划
??a.动态规划边界条件:底面上的最优值即为数字三角形的最后一层
??b.利用i循环,从倒数第二层推至第一层:

已知一个未排序嘚数组求这个数组最长上升子序列的长度。

已知一个二维数组其中存储了非负整数,找到从左上角到右下角的一条路径使得路径上嘚和最小。(移动过程中只能向下或向右)

已知一个二维数组左上角代表骑士的位置,右下角代表公主的位置二维数组存储整数,正數代表可以给骑士增加生命值负数会减少骑士的生命值,问骑士初始时至少是有多少生命值才可以保证骑士在行走的过程中至少保持苼命值为1.(骑士只能向下或向右行走)

直接思考动态规划,我们应该从左上向右下递推还是从右下向左上递推? 若用一个二伟数组代表每個格子的状态迁移算法,dp[i][j] 具体代表什么

若我们直接从左上角往右下角推,按照 LeetCode 64 的思路

我要回帖

更多关于 状态迁移算法 的文章

 

随机推荐