擊鼓傳花
阿新 • • 發佈:2018-11-12
題目描述
學校聯歡晚會的時候,為了使每一個同學都能參與進來,主持人常常會帶著同學們玩擊鼓傳花的遊戲。遊戲規則是這樣的:n個同學坐著圍成一個圓圈,指定一個同學手裡拿著一束花,主持人在旁邊背對著大家開始擊鼓,鼓聲開始之後拿著花的同學開始傳花,每個同學都可以把花傳給自己左右的兩個同學中的一個(左右任意),當主持人停止擊鼓時,傳花停止,此時,正拿著花沒傳出去的那個同學就要給大家表演一個節目。
聰明的小賽提出一個有趣的問題:有多少種不同的方法可以使得從小賽手裡開始傳的花,傳了m次以後,又回到小賽手裡。對於傳遞的方法當且僅當這兩種方法中,接到花的同學按接球順序組成的序列是不同的,才視作兩種傳花的方法不同。比如有3個同學1號、2號、3號,並假設小賽為1號,花傳了3次回到小賽手裡的方式有1->2->3->1和1->3->2->1,共2種。
輸入
輸入共一行,有兩個用空格隔開的整數n,m(3<=n<=30,1<=m<=30)
|
樣例輸入
3 3
|
輸出
輸出共一行,有一個整數,表示符合題意的方法數
|
樣例輸出
2
|
時間限制C/C++語言:1000MS其它語言:3000MS |
記憶體限制C/C++語言:65536KB其它語言:589824KB |
解析:1、首先我考慮到使用遞迴的方法解決,遞迴確實可以實現,不過會超時!!!不能通過!!!
def chuanhua(n,m,num):
nd = 0
if m == 0:
if num%n == 1:
nd = 1
else:
nd += chuanhua(n,m-1,(num+1)%n)
nd += chuanhua(n,m-1,(num-1)%n)
return nd
nm = [int(x) for x in input().split()]
n = nm[0]
m = nm[1]
print(chuanhua(n,m,1))
2、然後想到利用矩陣來解決,每行代表傳0~m次,每列表示編號為0~n-1的人,第零步時花在0上面,所以初始化d[0][0]=0,之後第一步,花可能傳到編號1或者編號n-1且傳遞方法都為1。所以d[i][j]表示在i次編號j拿到花的的傳遞方法數,
即 d[i][j] = d[i-1][(j-1)%n] + d[i-1][(j+1)%n]
題目問m次後第一個人手中的傳遞方法數,即d[m][0]
#-*-encoding:utf-8-*-
#python2
n,m = map(int,raw_input().split())
d = [[0]*n for i in range(m+1)]
d[0][0] = 1
for i in range(1,m+1):
for j in range(n):
d[i][j] = d[i-1][(j-1)%n] + d[i-1][(j+1)%n]
print(d[m][0])