题解 | #小招喵跑步#
小招喵跑步
https://www.nowcoder.com/practice/1177e9bd1b5e4e00bd39ca4ea9e4e216
解题思路
- 这是一个动态规划问题,需要找到到达目标位置的最少步数
- 状态转移方程:
- 当位置
能被2整除时:
(通过乘2操作到达)
- 当位置
不能被2整除时:
(要么+1,要么先+1再乘2)
- 当位置
- 基础情况:
代码
#include <iostream>
#include <vector>
using namespace std;
int move(int x) {
// 处理负数
if(x < 0) x = -x;
// 处理小于等于3的情况
if(x <= 3) return x;
vector<int> dp(x + 1);
// 初始化基础情况
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
// 动态规划填表
for(int i = 4; i <= x; i++) {
if(i % 2 == 0) {
dp[i] = dp[i/2] + 1;
} else {
dp[i] = min(dp[(i+1)/2] + 2, dp[i-1] + 1);
}
}
return dp[x];
}
int main() {
int x;
cin >> x;
cout << move(x);
return 0;
}
import java.util.Scanner;
public class Main {
public static int move(int x) {
// 处理负数
if(x < 0) x = -x;
// 处理小于等于3的情况
if(x <= 3) return x;
int[] dp = new int[x + 1];
// 初始化基础情况
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
// 动态规划填表
for(int i = 4; i <= x; i++) {
if(i % 2 == 0) {
dp[i] = dp[i/2] + 1;
} else {
dp[i] = Math.min(dp[(i+1)/2] + 2, dp[i-1] + 1);
}
}
return dp[x];
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
System.out.println(move(x));
}
}
def move(x):
# 处理负数
if x < 0:
x = -x
# 处理小于等于3的情况
if x <= 3:
return x
dp = [0] * (x + 1)
# 初始化基础情况
dp[1] = 1
dp[2] = 2
dp[3] = 3
# 动态规划填表
for i in range(4, x + 1):
if i % 2 == 0:
dp[i] = dp[i//2] + 1
else:
dp[i] = min(dp[(i+1)//2] + 2, dp[i-1] + 1)
return dp[x]
x = int(input())
print(move(x))
算法及复杂度
- 算法:动态规划
- 时间复杂度:
- 需要填充dp数组直到目标位置
- 空间复杂度:
- 需要一个长度为
的dp数组