小招喵喜欢在数轴上跑来跑去,假设它现在站在点n处,它只会3种走法,分别是:
1.数轴上向前走一步,即n=n+1
2.数轴上向后走一步,即n=n-1
3.数轴上使劲跳跃到当前点的两倍,即n=2*n
现在小招喵在原点,即n=0,它想去点x处,快帮小招喵算算最快的走法需要多少步?
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int x = Integer.parseInt(br.readLine());
if(x == 0){
System.out.println(x);
}else{
System.out.println(dfs((long)Math.abs(x)));
}
}
private static long dfs(long x) {
if(x == 0){
return 0;
}else if(x <= 2){
return x;
}
if((x & 1) == 0){
return dfs(x >> 1) + 1;
}else{
return Math.min(dfs((x - 1) >> 1) + 2, dfs((x + 1) >> 1) + 2);
}
}
} /*
参考答案;动态规划
dp[i]表示到达i点的最少步数。
最少就需要考虑两倍的走法
状态转移:
当前位置能被二整除,dp[i] = dp[i/2]+1;
当前位置不能被二整除,dp[i] = min(dp[i-1],dp[i+1/2]+1) + 1
dp[i+1/2]+1这个表示后移一步,比如说i=5,那么可以有dp[4] + 1,也可以有dp[6]+1,
而这里的dp[6]很显然是个偶数,那他的步数就一定是dp[3]+1
*/
import java.math.*;
import java.lang.Math;
import java.util.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader((new InputStreamReader(System.in)));
int x = Integer.parseInt(br.readLine());
if(x < 0){
x = -x;
}
if(x == 0){
System.out.println(0);
return;
}
int[] step = new int[x+1];
step[0] = 0;
step[1] = 1;
for(int i = 2; i < x + 1; i++){
if(i % 2 == 0){
step[i] = step[i/2]+1;
}else{
step[i] = Math.min(step[i -1], step[(i+1)/2]+ 1) + 1;
}
}
System.out.println(step[x]);
}
}