小招喵喜欢在数轴上跑来跑去,假设它现在站在点n处,它只会3种走法,分别是:
1.数轴上向前走一步,即n=n+1
2.数轴上向后走一步,即n=n-1
3.数轴上使劲跳跃到当前点的两倍,即n=2*n
现在小招喵在原点,即n=0,它想去点x处,快帮小招喵算算最快的走法需要多少步?
思路:
一个动态规划问题,小猫有两种跳跃方式:1. 一次走一步,2.一次走2倍与当前位置的步数。
dp方程:
dp[i-1] = min(dp[i-1], dp[i/2])+1 (i % 2 == 0)
dp[i-1] = min(dp[i-1], dp[(i+1)/2+1] + 1 (i % 2 != 0)
当i为偶数时,对于跳跃方式2来说,可以从前一个位置直接跳过来,即dp[i/2]。
当i为奇数时,对于跳跃方式2来说,需要在前一个位置跳过来需要两步,先方式2后方式1.
参考代码如下:
#include <vector> #include <iostream> #include <cmath> #include <algorithm> using namespace std; int deal(int x) { if (x < 2) { return x; } vector<int> dp(x + 1); dp[0] = 0; dp[1] = 1; for (int i = 2; i <= x; ++i) { if (i % 2 == 0) dp[i] = min(dp[i - 1], dp[i / 2]) + 1; else dp[i] = min(dp[i - 1], dp[(i + 1) / 2] + 1) + 1; } return dp[x]; } int main() { int n; while (cin >> n) { cout << deal(abs(n)) << endl; } return 0; }