xinyu04

导航

[Google] 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.

Given a target position target, return the length of the shortest sequence of instructions to get there.

Solution

并不是一道很好做的题目。每次既可以在同一个方向加速,或者选择相反的方向然后速度归 \(1\)。我们知道对于目标点,存在一个 \(n\) 满足:

\[2^{n-1}\leq target<2^n \]

对于一段连续的加速序列,我们可以用等比数列来得到总和:

\[1+2+...+2^{n-1} = 2^n-1 \]

如果直接满足,那么只需要 \(n\) 即可。否则一种方法就是先 pass, 然后 return.此时需要的 \(\#operation = n (pass) + 1 (reverse)\), 最后剩余的距离就是 \(2^n-1-target\)

另一种方法就是没有pass, 然后回退 \(m\)(反方向),再次reverse后前进:

\[\#operation = n-1(not\ pass)+1(reverse)+m(A)+1(reverse) \]

最后剩下的距离就是 \(i-2^{n-1}+2^m\)

最后值得注意的是:我们用记忆化来存储。

点击查看代码
class Solution {
private:
    int spd = 1;
    int pos = 0;
    int dp[10003];
public:
    int racecar(int target) {
        if(dp[target]>0)return dp[target];
        int n = floor(log2(target))+1;
        
        if((1<<n)-1==target) return dp[target]=n;
        
        else{
            // choice 1: pass then return
            dp[target] = n+1+racecar((1<<n)-1-target);
            for(int m = 0;m<n-1;m++)
                // choice 2
                dp[target] = min(dp[target], n+m+1+racecar(target-(1<<(n-1))+(1<<m)));
        }
        return dp[target];
    }
};

posted on 2022-07-18 21:47  Blackzxy  阅读(34)  评论(0编辑  收藏  举报