使用DP技术可以解决以下问题吗?
不需要代码。想法应该足够。
Marvel提出了一个名为Jumping Jack的新超级英雄。这个超级英雄的共同创造者是一位数学家,他为角色的力量增添了数学色彩。
因此,Jumping Jack最杰出的力量之一就是跳跃距离。但是,这个超级大国有一定的限制。
跳跃杰克只能跳跃—
因此,您需要帮助超级英雄开发一种算法,以最少的步骤到达目的地。目的地被定义为距离变为1的地方。跳跃的杰克应该跑完最后1公里!而且,他只能跳到离主要目的地整数倍距离的目的地。例如,如果他在10公里处,则跳过距离的1/3,就不能达到距离的10/3。他必须跳到5或9。
因此,您必须找到到达目的地所需的最小跳数。例如,如果目的地在10公里之外,则有两种方法可以到达目的地: 10-> 5-> 4-> 2-> 1(四跳) 10-> 9-> 3-> 1(三跳) 这些中的最小值是3,因此超级英雄至少需要跳跃3次才能到达该点。
答案 0 :(得分:0)
在解决所有动态编程问题时,请牢记以下两点:
始终尝试为手头的问题提供递归解决方案(现在不要直接着手研究递归解决方案,而是先自己尝试一下):
df_1[, paste0("Period_", windows) := frollmean(Dist, windows)]
现在您知道我们已经设计了一个递归解决方案。下一步是将解决方案存储在一个数组中,以便将来可以使用它并避免重新计算。您可以简单地获取一维整数数组并继续存储它。
请记住,如果您采用自上而下的方法-称为记忆,而如果采用自下而上的方法-则称为动态编程。看看this,看看这两种方法之间的确切区别。
一旦您有了递归解决方案,现在就可以考虑构造一个自底向上的解决方案或自顶向下的解决方案。
在自下而上的解决方案策略中-您首先填写基本案例(calCulateMinJumps(int currentDistance) {
if(currentDistance == 1) {
// return jumps - you don't need to recurse here
} else {
// find at what all places you can jump
jumps1 = calculateMinJumps(n-1) + 1
if(currentDistance % 2 == 0)
jumps2 = calculateMinJumps(n/2) + 1
if(currentDistance % 3 == 0)
jumps3 = calculateMinJumps(n/3) + 1
return minimum(jumps1, jumps2, jumps3) // takes jump2 and jump3 only if they are valid
}
}
),然后在其基础上进行构建以达到最终所需的解决方案。
现在,我没有给您完整的策略,因为这将是您要执行的任务。您确实会找到解决方案。 :)-根据您的请求-Jumping Jack should cover the last 1 km running!
。
答案 1 :(得分:0)
首先,请考虑一下这个硬币兑换问题,可能会帮助您了解自己的硬币问题,两者基本相同: Coin change - DP
其次,通常,如果您知道自己的问题有DP解决方案,则可以执行4个步骤来解决它。当然,您可以省略前三个步骤中的一个或全部。
根据回溯解决方案查找问题的递归公式。 (稍后描述)
根据递归公式编写递归代码。(略)
最后,对于您的问题,该公式并不难找出:
minStepFor(distance_N)=Math.min(minStepFor(distance_N-1)+1),
minStepFor(distance_N/2)+1,
minStepFor(distance_N/3)+1)
想象一下杰克正站在距离N点处,而他第一次走最多有三个选择:转到N-1
点,N/2
点或N/3
点(如果N/2
或N/3
不是整数,则他的选择将减少。)
对于他的每一个选择,最小步幅均为minStepFor(left distance)+1
,因为他已经进行了1步移动,并且肯定地,他将尝试在其左移步幅中进行最小步幅。每个选择的left distance
是distance_N-1
,distance_N/2
和distance_N/3
。
这就是理解公式的方式。有了它,不难编写一个递归解决方案。
答案 2 :(得分:0)
考虑f [1] = 0,因为JumpingJack离1公里远时所需的跳数没有。 使用该基值以以下方式解决F [2] ... f [n]
for(int i=2; i<=n; i++) {
if(i%2==0 && i%3==0) {
f[i] = Math.min(Math.min(f[i-1]+1, f[i/2]+1), f[i/3] + 1);
}
if(i%2==0) {
f[i] = Math.min(f[i-1]+1, f[i/2]+1);
}else if(i%3==0) {
f[i] = Math.min(f[i-1]+1, f[i/3] + 1);
}else{
f[i] = f[i-1]+1;
}
}
return f[n];
您无需多次递归地解决子问题!