对动态规划算法的理解及相关题目分析

1、对动态规划算法的理解

(1)基本思想:

动态规划算法的基本思想与分治法类似:将待求解的问题分解成若干个子问题,先求解子问题,然后从这些子问题的解中得到原问题的解。但是,与分治法不同的是,为了避免重复多次计算子问题,动态规划算法用一个表记录所有已解决的子问题的答案,不管该子问题以后是否被利用,只要它被计算过,就将其结果填入表中。

(2)设计动态规划算法的步骤:

①找出最优解的性质,并刻画其结构特征

②递归地定义最优值

③以自底向上的方式计算最优值

④根据计算最优值时得到的信息构造最优解

(3)动态规划算法的基本要素

最优子结构性质

当问题的最优解包含了子问题的最优解时,称该问题具有最优子问题结构。在动态规划算法中,利用问题的最优子结构性质,以自底向上的方式递归地从子问题的最优解逐步构造出整个问题的最优解。

重叠子问题性质

在用递归算法自顶向下解决问题时,每次产生的子问题并不总是新问题,有些子问题可能被反复计算多次。动态规划算法利用这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,当再次需要解此子问题时,只需要简单地用常数时间查看一下结果即可。

从一般意义上讲,问题所具有的最优子结构性质和重叠子问题性质是该问题可用动态规划算法求解的基本要素。

备忘录方法

备忘录方法是动态规划算法的变形。与动态规划算法一样,备忘录方法用表格保存已解决的子问题的答案,在下次解决问题时,只要简单地查看该子问题的解答,不必再次计算。与动态规划算法不同的是,备忘录方法的递归方式是自顶向下的,而动态规划算法则是自底向上的。

备忘录方法为每个子问题建立一个记录项,初始化时,该记录项存入一个特殊的值,表示该子问题尚未求解。在求解的过程中对每个待求解的子问题,首先查看相应的记录项。若记录项存储的是初始化的特殊值,则需要计算该子问题的解,并保存在相应的记录项中已备以后查看。若记录项存储的不是初始值,则表示该子问题已被计算过,此时记录项存储的值即该子问题的解答。

2、例题的递归方程分析

(1)租用游艇问题:长江游艇俱乐部在长江上设置了n个游艇出租站1,2,…,n。游客可在这些游艇出租站租用游艇,并在下游的任何一个游艇出租站归还游艇。游艇出租站i到游艇出租站j之间的租金为r(i,j),1<=i<j<=n。试设计一个算法,计算出从游艇出租站1 到游艇出租站n所需的最少租金。

 1 #include <iostream>
 2 using namespace std;
 3 int main()
 4 {
 5     int n;//n代表游艇出租站的数量
 6     int cost[100][100];//cost[i][j]表示第i站到第j站所需要的租金
 7     cin>>n;
 8     for(int i=1;i<n;i++) {
 9         for(int j=i+1;j<=n;j++){
10             cin>>cost[i][j];//输入i->j站的价格
11         }
12     }
13     for(int m=2;m<n;m++) {//m表示要经过的出租站点
14         for(int i=1;i<=n-m;i++) {//i表示起始出租站,保证最后一段为m,所以循环截止到i<=n-m;
15             int j = i+m;//j表示要到达的出租站,而起始站为i,故j=i+m
16             for(int t=i+1;t<=j;t++) {
17                 int temp = cost[i][t] + cost[t][j];//计算i->t站和t->j站租金之和
18                 if(cost[i][j] > temp) //比较直接从i->j站的租金便宜还是从i->t、再从t->j站便宜
19                     cost[i][j] = temp;//交换成较便宜的租金价格,直至最后第一排最后一个的值为最小租金
20             }
21         }
22     }
23     cout<<cost[1][n];
24     return 0;
25 } 

(2)单调递增最长子序列:设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列的长度。

 1 int longest(int a[], int n)
 2 {//求最长单调递增子序列的长度,形参是长度为n的数组a
 3     int length[n];//数组length[i]用于在数组a中记录比a[i]小的数的个数
 4     int max = 1;//表示最长长度,初始化为1
 5     for (int i = 0; i < n; i++){
 6         length[i] = 1;//数组length初始化为1
 7     }
 8     for (int i = 1; i < n; i++) {
 9         for (int j = 0; j < i; j++) {
10             if (a[j] < a[i] && length[j] + 1 >length[i]) {//如果前一个数j小于后一个数i
11                 length[i] = length[j] + 1;//则length数组中i对应位置的值变成j对应位置的值加1,表示存在多一个小于a[i]的数
12                 if (max < length[i]) {
13                     max = length[i];//将值赋给max
14                 }
15             }
16         }
17     }
18     return max;//返回最长的长度
19 }

3、说明结对编程情况

一开始并不清楚怎么运用动态规划算法来分析和完成题目,于是和小伙伴一起认真地讨论题目的内容,研究了到底什么是动态规划算法,再尽量地去理解它的思想之后,和两个小伙伴一起完成这两道编程题。在这个过程中,照着自己的理解、小伙伴们的讨论以及借鉴了别的同学的建议和提醒,最终顺利地完成了任务。

原文地址:https://www.cnblogs.com/CYUCHUN/p/9853308.html

时间: 2024-10-19 20:54:59

对动态规划算法的理解及相关题目分析的相关文章

动态规划算法的理解

什么是动态规划算法? 动态规划算法其实质就是分治思想和解决冗余.因此它与分治法和贪心法类似,都是将待求解问题分解为更小的,相同的子问题,然后对子问题进行求解,最终产生一个整体最优解. 适合采用动态规划法求解的问题,经分解得到的各个子问题往往不是相互独立的.在求解过程中,将已解决的子问题的解进行保存,在需要时可以轻松地找出. 示例如下: Fibonacci数列       0   n=0 f(n)=  1   n=1 f(n-1)+f(n-2)    n>1 如果n=4,则f(4)=f(3)+f(

动态规划算法相关问题

1.对动态规划算法的理解 基本思想: 动态规划算法是将待求解的问题分解成若干个子问题,先求子问题,然后从这些子问题的解得到原问题的解.但与分治法不同,适合于用动态规划法求解的问题,经分解得到的子问题往往不是互相独立的.为了避免有些子问题被重复计算了很多次,可以用一个表来记录所有已解决的子问题的答案,不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中. 基本步骤: (1)找出最优解的性质,并刻画其结构特征 (2)递归地定义最优解 (3)以自底向上的方式计算出最优解 (4)根据计算最优值

动态规划算法解最长公共子序列LCS问题

第一部分.什么是动态规划算法 ok,咱们先来了解下什么是动态规划算法. 动态规划一般也只能应用于有最优子结构的问题.最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似).简单地说,问题能够分解成子问题来解决. 动态规划算法分以下4个步骤: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值   //此3步构成动态规划解的基础. 由计算出的结果构造一个最优解.   //此步如果只要求计算最优解的值时,可省略. 好,接下来,咱们

浅谈我对动态规划的一点理解---大家准备好小板凳,我要开始吹牛皮了~~~

前言 作为一个退役狗跟大家扯这些东西,感觉确实有点...但是,针对网上没有一篇文章能够很详细的把动态规划问题说明的很清楚,我决定还是拿出我的全部家当,来跟大家分享我对动态规划的理解,我会尽可能的把所遇到的动态规划的问题都涵盖进去,博主退役多年,可能有些地方会讲的不完善,还望大家多多贡献出自己的宝贵建议,共同进步~~~ 概念 首先我们得知道动态规划是什么东东,百度百科上是这么说的,动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process

野生前端的数据结构练习(11)动态规划算法

一.动态规划算法 dynamic programming被认为是一种与递归相反的技术,递归是从顶部开始分解,通过解决掉所有分解出的问题来解决整个问题,而动态规划是从问题底部开始,解决了小问题后合并为整体的解决方案,从而解决掉整个问题. 动态规划在实现上基本遵循如下思路,根据边界条件得到规模较小时的解,小规模问题合并时依据递推关系式进行,也就是说较大规模的问题解可以由较小问题的解合并计算得到.最经典易懂的就是使用递归算法和动态规划算法两种不同的方式来计算斐波那契数列或求阶乘的对比,动态规划算法的特

动态规划算法(Dynamic Programming,简称 DP)

动态规划算法(Dynamic Programming,简称 DP)似乎是一种很高深莫测的算法,你会在一些面试或算法书籍的高级技巧部分看到相关内容,什么状态转移方程,重叠子问题,最优子结构等高大上的词汇也可能让你望而却步. 而且,当你去看用动态规划解决某个问题的代码时,你会觉得这样解决问题竟然如此巧妙,但却难以理解,你可能惊讶于人家是怎么想到这种解法的. 实际上,动态规划是一种常见的「算法设计技巧」,并没有什么高深莫测,至于各种高大上的术语,那是吓唬别人用的,只要你亲自体验几把,这些名词的含义其实

[LeetCode] 时间复杂度 O(n),空间复杂度 O(1) 的动态规划算法,题 Jump Game

Jump Game Given an array of non-negative integers, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Determine if you are able to reach the last index. For ex

动态规划算法之滚动数组的求解(C++)

虽然接触动态规划算法已经有一段时间,给一个01背包问题,能够做到一个表格简单粗暴下去,然后求得结果,但心里总觉得对这个算法理解十分不到位,抱着对算法的热爱,网上很多大牛的算法思维实在让我佩服的五体投地.在此讲一讲动态规划中滚动数组的求解方法,算是对这个知识点做一个记录,也希望有写的不妥的地方,大家能不吝赐教. 首先,我们先看看"滚动数组"的例题,大家可以参考http://www.lintcode.com/en/problem/house-robber/ 题意大概就是说:一个盗贼要去偷盗

动态规划算法(转载)

动态规划算法 例题1: https://segmentfault.com/a/1190000008244955 例题2: https://segmentfault.com/a/1190000007927865 讲解: http://www.hawstein.com/posts/dp-novice-to-advanced.html 顶级讲解动态规划:http://www.cnblogs.com/SDJL/archive/2008/08/22/1274312.html(本文转载自此文) 下面是原文: