2021-02-14:假设有排成一行的N个位置,记为1~N,N 一定大于或等于 2,开始时机器人在其中的M位置上(M 一定是 1~N 中的一个)。如果机器人来到1位置,那么下一步只能往右来到2位置;如果机器人来到N位置,那么下一步只能往左来到 N-1 位置;如果机器人来到中间位置,那么下一步可以往左走或者往右走;规定机器人必须走 K 步,最终能来到P位置(P也是1~N中的一个)的方法有多少种?

2021-02-14:假设有排成一行的N个位置,记为1~N,N 一定大于或等于 2,开始时机器人在其中的M位置上(M 一定是 1~N 中的一个)。如果机器人来到1位置,那么下一步只能往右来到2位置;如果机器人来到N位置,那么下一步只能往左来到 N-1 位置;如果机器人来到中间位置,那么下一步可以往左走或者往右走;规定机器人必须走 K 步,最终能来到P位置(P也是1~N中的一个)的方法有多少种?给定四个参数 N、M、K、P,返回方法数。

福哥答案2021-02-14:

自然智慧即可。
1.递归。有代码。
两种情况。左移、右移。
2.带dp的递归。有代码。
3.动态规划。有代码。
dp[i][j],i是机器人位置,j是剩余步数。
dp[i][j]依赖左上和左下。见图。
dp[i][j]=【左上】+【左下】。
4.另一种递归。有代码。

代码用golang编写,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main
 
import "fmt"
 
func main() {
    fmt.Println("1.递归:", RobotWalk1(5, 2, 4, 6))
    fmt.Println("2.带dp的递归:", RobotWalk2(5, 2, 4, 6))
    fmt.Println("3.动态规划:", RobotWalk3(5, 2, 4, 6))
    fmt.Println("4.另一种递归:", RobotWalk4(5, 2, 4, 6))
}
 
func RobotWalk1(N int, start int, aim int, K int) int {
    if N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1 {
        return -1
    }
    return process1(start, K, aim, N)
}
 
// 机器人当前来到的位置是cur,
// 机器人还有rest步需要去走,
// 最终的目标是aim,
// 有哪些位置?1~N
// 返回:机器人从cur出发,走过rest步之后,最终停在aim的方法数,是多少?
func process1(cur int, rest int, aim int, N int) int {
    if rest == 0 { // 如果已经不需要走了,走完了!
        if cur == aim {
            return 1
        } else {
            return 0
        }
    }
    // (cur, rest)
    if cur == 1 { // 1 -> 2
        return process1(2, rest-1, aim, N)
    }
    // (cur, rest)
    if cur == N { // N-1 <- N
        return process1(N-1, rest-1, aim, N)
    }
    // (cur, rest)
    return process1(cur-1, rest-1, aim, N) + process1(cur+1, rest-1, aim, N)
}
 
func RobotWalk2(N int, start int, aim int, K int) int {
    if N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1 {
        return -1
    }
    dp := make([][]int, N+1)
    for i := 0; i < N+1; i++ {
        dp[i] = make([]int, K+1)
    }
    for i := 0; i <= N; i++ {
        for j := 0; j <= K; j++ {
            dp[i][j] = -1
        }
    }
    // dp就是缓存表
    // dp[cur][rest] == -1 -> process1(cur, rest)之前没算过!
    // dp[cur][rest] != -1 -> process1(cur, rest)之前算过!返回值,dp[cur][rest]
    // N+1 * K+1
    return process2(start, K, aim, N, dp)
}
 
// cur 范: 1 ~ N
// rest 范:0 ~ K
func process2(cur int, rest int, aim int, N int, dp [][]int) int {
    if dp[cur][rest] != -1 {
        return dp[cur][rest]
    }
    // 之前没算过!
    ans := 0
    if rest == 0 {
        if cur == aim {
            ans = 1
        } else {
            ans = 0
        }
    } else if cur == 1 {
        ans = process2(2, rest-1, aim, N, dp)
    } else if cur == N {
        ans = process2(N-1, rest-1, aim, N, dp)
    } else {
        ans = process2(cur-1, rest-1, aim, N, dp) + process2(cur+1, rest-1, aim, N, dp)
    }
    dp[cur][rest] = ans
    return ans
 
}
 
func RobotWalk3(N int, start int, aim int, K int) int {
    if N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1 {
        return -1
    }
    dp := make([][]int, N+1)
    for i := 0; i < N+1; i++ {
        dp[i] = make([]int, K+1)
    }
    dp[aim][0] = 1
    for rest := 1; rest <= K; rest++ {
        dp[1][rest] = dp[2][rest-1]
        for cur := 2; cur < N; cur++ {
            dp[cur][rest] = dp[cur-1][rest-1] + dp[cur+1][rest-1]
        }
        dp[N][rest] = dp[N-1][rest-1]
    }
    return dp[start][K]
}
 
//递归
func RobotWalk4(N int, start int, aim int, K int) int {
    ansVal := 0
    ans := &ansVal
    process4(N, start, K, aim, ans)
    return *ans
}
 
//N个位置,固定
//M是起始位置
//K步
//P是最终位置,固定
func process4(N int, M int, K int, P int, ans *int) {
    if M < 1 || M > N {
        return
    }
    if K == 0 {
        if M == P {
            *ans++
        }
        return
    }
    process4(N, M-1, K-1, P, ans)
    process4(N, M+1, K-1, P, ans)
 
}

  

执行结果如下:

 

 

***
[左神java代码](https://github.com/algorithmzuo/algorithmbasic2020/blob/master/src/class18/Code01_RobotWalk.java)
[评论](https://user.qzone.qq.com/3182319461/blog/1613259761)

posted @   福大大架构师每日一题  阅读(333)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示