跳石板题目描述:
小易来到了一条石板路前,每块石板上从1挨着编号为:1、2、3…
这条石板路要根据特殊的规则才能前进:对于小易当前所在的编号为K的 石板,小易单次只能往前跳K的一个约数(不含1和K)步,即跳到K+X(X为K的一个非1和本身的约数)的位置。 小易当前处在编号为N的石板,他想跳到编号恰好为M的石板去,小易想知道最少需要跳跃几次可以到达。
例如:
N = 4,M = 24:
4->6->8->12->18->24
于是小易最少需要跳跃5次,就可以从4号石板跳到24号石板
思路:
- 这题我们用动态规划的思想,将N~M个石板看做成一个一维数组stepNum[i],其中数组中存储着N到当前位置的最小步数,如果是0说明i号石板无法经过。
- 我们从N号石板开始进行遍历,记录他所能达到的所有下一个石板位置,并记录在stepNum[i]中,这样遍历完所有石板后,先不考虑其他,我们应该能得出:如果stepNum[i]中有的元素任然为0,则该石板不能经过。
- 而在遍历的过程中,我们势必会遇到同一块石板有不同的步数到达,这时候就需要我们进行选择了,选择之前的到达该石板步数和当前步数+1两者最小的,这就是我们的动态规划状态转移方程:
stepNum[divNum[j]+i]=min(stepNum[divNum[j]+i],stepNum[i]+1) - 经过遍历一次后得到结果,jumpNum[M]就是从N开始加,加到M的最少次数,如果是0,说明不可能加到M
例子:4—>24
- i=4(2x2):4(1)->6(2)
- i=5(无):stepNum[5]==0 continue;
- i=6(2x3):4(1)->6(2)->8(3) or 4(1)->6(2)->9(3)
- i=7(无):stepNum[7]==0 continue;
- i=8(2x4):4(1)->6(2)->8(3)->10(4) or 4(1)->6(2)->8(3)->12(4)
- i=9(3x3):4(1)->6(2)->9(3)->12(4)
- i=10(2x5):4(1)->6(2)->8(3)->10(4)->12(5)
- stepNum[12]=4,stepNum[10]+1=5,说明此时到达12号的石板的步数并非最优解,stepNum[12]=min(stepNum[12],stepNum[10]+1,stepNum[12]选二者最小值4。
详细代码:
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
void divisorNum(int n,vector<int>& divNum)

这篇博客通过实例解析了如何运用动态规划解决跳石板问题。小易从编号N的石板出发,目标是跳到编号M的石板,每次跳跃只能跳到当前石板的一个非1和本身的约数位置。博主详细介绍了动态规划的状态转移方程,并提供了代码实现,最终得出最少跳跃次数。
&spm=1001.2101.3001.5002&articleId=110871444&d=1&t=3&u=418fac7b833c453f8e8a6aeac41d9d7a)
659

被折叠的 条评论
为什么被折叠?



