动态规划之跳石板
解法框架
待定
跳石板
动态规划——有很多解,但是要求最优的那一个。动态规划的核心思想就是已经解决的问题要能被后面所利用。
采用下面的思维导图,梳理以下过程。跳石板的时候每次能跳得距离只能是当前石板的编号的约数(除了1和本身)。
下图中,已经把从4跳到24的所有可能情况列了出来(由于篇幅限制,所以像7,11等这种情况就忽略了),用一个数组step保存从4开始到达每个石板数字的步数,比如step[8]=3,表示从4跳到8需要三步(这里把自己跳到自己身上算作1次),在初始情况下,除了step[4]=1(step[4]设置为1)之外的所有数字,全部设为一个很大的数,表示不可到达(下面思维导图中,用恶魔头像表示)
- 括号中的数字表示到达该数字的步数
首先从4开始,对于4来说,只有一个约数2,所以它只能跳到6,当它的来到6之前需要进行判断:一是到达的石板编号是否已经超越了目标石板编号,二是到达的石板是否为max,即是否是不可到达。所以这里到达6之后,判断第二个条件,6它是一个不可到达的石板,那么我们就直接就step[6]=step[4]+1,表示只需一步
来到6之后,它有两个选择,分别可以到达8和9,所以按照上述步骤,继续更新
对于8也是如此,对于9也是一样
所以大家可以发现,位于同一层级其实就表示步数是相同的,在当前情况下,走哪一条都可以
对于10,当他来到12时,此时由于之前8已经将12给更新了,所以从10到达12时,进行判断时m,12不是不可到达的一个石板,而是有确定的编号的,即step[12]=4,因此10在更新12时要进行一个比较:step[10+2]小还是step[10]+1小,很明显这里step[10+2]=step[12]=4<step[10]+1=4+1<5,因此step[12]继续保持为4,同时由10到12再到24这一条路线其实已经就pass了
接下来的过程就是重复上述过程了
代码
首先写出基本框架
#include <iostream> #include <vector> #include <math.h> #include <limits.h> using namespace std;int Jump(int N,int M) {return 0;}int main() {int N,M;//起始石板编号和终止石板编号cin>>N>>M;cout<<Jump(N,M)<<endl;}第二步编写Jump函数
- 建立一个step数组,用来存储到达某一个点的步数,比如step[8]=3,表示从4到8需要2步(因为step[4]设置为1)
- 初始化step数组,除了起始点外,其余均设置为INT_MAX(头文件为limits.h)
- for循环从N到M跳跃,遍历时如果某个点,比如step[i]==INT_MAX表示此点不可达,直接下一个.
- 中间编写一个函数用于获取当前石板的所有约束,存储在一个数组当中,然后遍历这个数组,判断方法和上面的图中展示时一致的
总结
- 上一篇: 实验一 OpenGL初识
- 下一篇: (王道408考研数据结构)第八章排序-第