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.

Approach #1: C++. [DFS]

class Solution {
public:
    int racecar(int target) {
        queue<pair<int, int>> q;
        q.push({0, 1});
        unordered_set<string> v;
        v.insert("0_1");
        v.insert("0_-1");
        int steps = 0;
        while (!q.empty()) {
            int size = q.size();
            while (size--) {
                auto p = q.front(); q.pop();
                int pos = p.first;
                int speed = p.second;
                {
                    int pos1 = pos + speed;
                    int speed1 = speed * 2;
                    pair<int, int> p1{pos1, speed1};
                    if (pos1 == target) return steps+1;
                    if (p1.first > 0 && p1.first < 2 * target)
                        q.push(p1);
                }
                {
                    int speed2 = speed > 0 ? -1 : 1;
                    pair<int, int> p2{pos, speed2};
                    string key2 = to_string(pos) + "_" + to_string(speed2);
                    if (!v.count(key2)) {
                        q.push(p2);
                        v.insert(key2);
                    }
                }
            }
            steps++;
        }
        return -1;
    }
};

  

Approach #2: Java. [DP]

class Solution {
    private static int[][] m;
    public int racecar(int target) {
        if (m == null) {
            final int kMaxT = 10000;
            m = new int[kMaxT + 1][2];
            for (int t = 1; t <= kMaxT; ++t) {
                int n = (int)Math.ceil(Math.log(t + 1) / Math.log(2));
                if (1 << n == t + 1) {
                    m[t][0] = n;
                    m[t][1] = n + 1;
                    continue;
                }
                int l = (1 << n) - 1 - t;
                m[t][0] = n + 1 + Math.min(m[l][1], m[l][0] + 1);
                m[t][1] = n + 1 + Math.min(m[l][0], m[l][1] + 1);
                for (int i = 1; i < t; ++i) {
                    for (int d = 0; d <= 1; ++d) {
                        m[t][d] = Math.min(m[t][d], Math.min(
                            m[i][0] + 2 + m[t-i][d],
                            m[i][1] + 1 + m[t-i][d]));
                    }
                }
            }
        }
        return Math.min(m[target][0], m[target][1]);
    }
}

  

Approach #3: Python. [DP]

class Solution(object):
    def __init__(self): self.dp = {0: 0}
    
    def racecar(self, t):
        """
        :type target: int
        :rtype: int
        """
        if t in self.dp: return self.dp[t]
        n = t.bit_length()
        if 2**n - 1 == t: self.dp[t] = n
        else:
            self.dp[t] = self.racecar(2**n - 1 - t) + n + 1
            for m in range(n-1):
                self.dp[t] = min(self.dp[t], self.racecar(t - 2**(n-1) + 2**m) + n + m + 1)
        return self.dp[t]

  

Analysis:

http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-818-race-car/

永远渴望,大智若愚(stay hungry, stay foolish)
原文地址:https://www.cnblogs.com/h-hkai/p/10165176.html