算法提高 超級瑪麗(動態(tài)規(guī)劃)
問題描述
大家都知道"超級瑪麗"是一個很善于跳躍的探險家,他的拿手好戲是跳躍,但它一次只能向前跳一步或兩步。有一次,他要經(jīng)過一條長為n的羊腸小道,小道中有m個陷阱,這些陷阱都位于整數(shù)位置,分別是a1,a2,....am,陷入其中則必死無疑。顯然,如果有兩個挨著的陷阱,則瑪麗是無論如何也跳過不去的。
現(xiàn)在給出小道的長度n,陷阱的個數(shù)及位置。求出瑪麗從位置1開始,有多少種跳躍方法能到達勝利的彼岸(到達位置n)。
輸入格式
第一行為兩個整數(shù)n,m
第二行為m個整數(shù),表示陷阱的位置
輸出格式
一個整數(shù)。表示瑪麗跳到n的方案數(shù)
樣例輸入
4 1
2
樣例輸出
1
方法一
思路:
從題意中我們知道這是一個臺階題只不過添加了一個不可以跳到陷阱里面的條件。我們知道臺階題是個經(jīng)典的dfs遞歸題。我們可以知道題目中走臺階的步數(shù)可以一1步,也可以是2步。那么我們就可以知道函數(shù)的走的方法就是 dfs(x+1) dfs(x+2) 。我們到小道的長度時就存一種可能,那陷阱的話意思就是當我們走到陷阱時就應該退回當前的走法,換下種可能,那我們可以用數(shù)組存儲陷阱然后當函數(shù)中的步數(shù)走道次陷阱就退回。
程序:
n,m=map(int,input().split())
a=list(map(int,input().split())) #存儲陷阱的位置
con=0
def dfs(x):
global con
if x>=n: #到小路距離和超過時
if x==n:
con+=1
return
if a.count(x)==1: #排除走到陷阱的可能
return
dfs(x+1)#走1步
dfs(x+2)#走2步
dfs(1)
print(con)
方法二
思路:
我們有可以用動態(tài)規(guī)劃的思想,當我們知道之前的步數(shù)時就可以用當前的小路長度減去可以走的步數(shù)累加就可以得到當前的次數(shù)。dp[i]=dp[i-1]+dp[i-2] 因為我們可以知道i-1 的可能數(shù)和i-2的可能數(shù),i-1就是我現(xiàn)在最后一步走的是1步,如果當前是陷阱的時候就可以可能的步數(shù)。
程序:
n,m=map(int,input().split())
a=list(map(int,input().split()))#存儲陷阱的位置
dp=[1 for i in range(50)]
dp[0]=0
for i in range(1,n+1): #當前的步數(shù)
if a.count(i)==1:
dp[i]=0
else:
dp[i]=dp[i-1]+dp[i-2] #最后一步是1步的可能和2步的可能的累加值
print(dp[n])
禁止轉(zhuǎn)載。僅用于自己學習。對程序錯誤不負責。