[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\) 满足:
对于一段连续的加速序列,我们可以用等比数列来得到总和:
如果直接满足,那么只需要 \(n\) 即可。否则一种方法就是先 pass, 然后 return.此时需要的 \(\#operation = n (pass) + 1 (reverse)\), 最后剩余的距离就是 \(2^n-1-target\)
另一种方法就是没有pass, 然后回退 \(m\)(反方向),再次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];
}
};