一个环上有10个点,编号为0-9,从0点出发,每步可以顺时针到下一个点,也可以逆时针到上一个点,求:经过n步又回到0点有多少种不同的走法?
举例:n=1, 0->1或者0->9,回不到0点,共0种走法;n=2, 0->1->0, 0->1->2, 0->9->0, 0->9->8, 有2种走法回到0点
```go
package main
import (
"fmt"
"os"
"strconv"
)
var result = 0
func main() {
var buffer [512]byte
n, err := os.Stdin.Read(buffer[:])
if err != nil {
fmt.Println(err)
return
}
testNum, err := strconv.Atoi(string(buffer[:n-1]))
if err != nil {
fmt.Println(err)
return
}
if testNum%2 != 0 {
fmt.Println(testNum, " is not Oushu")
return
}
step(testNum, 0)
fmt.Println(result)
}
func step(num int, record int) {
num--
if num < 0 {
return
} else {
record++
if num == 0 {
if (record+num*10)%10 == 0 {
result++
}
}
step(num, record)
record -= 2
if num == 0 {
if (record+num*10)%10 == 0 {
result++
}
}
step(num, record)
}
}
```
上面我用迭代写的,但是算100步都卡在那里,等半天算不出,复杂度太高了,大神们给个最优解,面试老师说用动态规划,网上查了但没理解,求助
这道题因为是10个单位的环,所以n一定要是偶数才能满足要求,要是奇数个单位的环也可以这样做。那么N和M在这道题里怎么取值呢?首先N+M=n,要么N=M,要么N-M=10*(正整数),要么M-N=10*(正整数)。(这里隐含条件n应该是不为0的)
0<n<10,n=M+N,只能N=M,有C(2N,N)种排法;
10<=n<20,n=M+N;N=M时,有C(2N,N)种排法;
N-M=10时,有C(N+M,N)种;
M-N=10时,有C(N+M,M)种;
20<=n<30,n=M+N;N=M时,有C(2N,N)种排法;
N-M=10时,有C(N+M,N)种;
M-N=10时,有C(N+M,M)种;
N-M=20时,有C(N+M,N)种;
M-N=20时,有C(N+M,M)种;
#2
更多评论
自己解答一下:抽象化为另一种描述,有N个相同白球,M个相同黑球,排成一列,有多少种排列?这就是一道高中数学的组合问题,相当于从N+M个位置取N个位置放白球
#1