[Leetcode] 818. Race Car 解题报告

题目

Your car starts at position 0 and speed +1 on an infinite number line.  (Your car can go into negative positions.)

Your car drives automatically according to a sequence of instructions A (accelerate) and R (reverse).

When you get an instruction "A", your car does the following: position += speed, speed *= 2.

When you get an instruction "R", your car does the following: if your speed is positive then speed = -1 , otherwise speed = 1.  (Your position stays the same.)

For example, after commands "AAR", your car goes to positions 0->1->3->3, and your speed goes to 1->2->4->-1.

Now for some target position, say the length of the shortest sequence of instructions to get there.

Example 1:
Input: 
target = 3
Output: 2
Explanation: 
The shortest instruction sequence is "AA".
Your position goes from 0->1->3.
Example 2:
Input: 
target = 6
Output: 5
Explanation: 
The shortest instruction sequence is "AAARA".
Your position goes from 0->1->3->7->7->6.

 Note:

  • 1 <= target <= 10000.

思路

采用动态规划的思路,定义dp[target]表示行驶长度为target的距离所需要的最小指示个数。可以证明有如下两种可能性:

1)如果target刚好是可以由“AAA...AR”(一共n步)达到,也就是说前面一路加速,最后再减速到-1,那么这种走法就是最优选择;

2)如果不满足条件1),那么最优解就有多种可能性了:a)第一次冲过target的时候进行‘R’操作,然后反向再接近target。此时我们已经走了n+1步,并且和target的距离已经减少到了(1 << n) - 1 - target,所以我们可以递归地调用rececar函数;b)前面先走m步(可以通过递归调用racecar函数得到最优值),然后再采用1)的策略。最终的答案就是a)和b)的各种可能性的最小值。

为了达到最优的运行效率,我们采用dp + memorization的策略:每当需要计算一个子问题时,首先查表看看该子问题是否已经被计算过了;如果是,则直接返回结果;否则我们再进行计算,并且将结果保存下来,以备后面的计算再次使用。

代码

class Solution {
public:
    int racecar(int target) {
        if (dp[target] > 0) {                       // already calculated before
            return dp[target];
        }
        int n = floor(log2(target)) + 1, res;
        if (1 << n == target + 1) {                 // perfect solution: just use someting like "AAA...AR"
            dp[target] = n;
        }
        else {                                      // need to go back using the same strategy
            dp[target] = racecar((1 << n) - 1 - target) + n + 1;
            for (int m = 0; m < n - 1; ++m) {
                dp[target] = min(dp[target], racecar(target - (1 << (n - 1)) + (1 << m)) + n + m + 1);
            }
        }
        return dp[target];
    }
private:
    int dp[10001];
};

猜你喜欢

转载自blog.csdn.net/magicbean2/article/details/80333734
car
今日推荐