1.丟雞蛋問題,已知k個雞蛋,n層樓,求投擲雞蛋最小次數(能夠判斷雞蛋摔破的樓層)
若在第i層,有乙個雞蛋時:
1)摔碎:則需嘗試投擲 i-1次,即dp[i-1]
2)未摔碎:則需嘗試投擲 n-i次,即dp[n-i]
3)則共需max(dp[i-1],dp[n-i]) +1 ,1為本次投擲
若在第i層,有k個雞蛋時:
1)摔碎:則有k-1個雞蛋,需嘗試投擲 i-1次,即dp[k-1][i-1]
2)未摔碎:則有k個雞蛋,需嘗試投擲 n-i次,即dp[k][n-i]
3)則共需max(dp[k-1][i-1],dp[k-1][n-i])+1 的最小值 ,其中dp[1][i-1]=i-1
2.此時我們採取逆向思路
1.丟雞蛋問題,已知k個雞蛋,我們最少需要投擲i次,則我們在那一層?:
1)摔碎:則我們在dp[k-1][i-1]層
2)未摔碎:則我們在dp[k][i-1]層
3)則有,dp[k][i]=dp[k-1][i-1]+dp[k-1][i-1]+1
很顯然,第乙個雞蛋要從x層扔下去,如果爛了,還可以用另外乙個雞蛋從第一層向上開始扔。
現在,希望至少 扔雞蛋 x 次,就可以判斷出100層樓。那就假設雞蛋一直沒爛,第一次扔完雞蛋之後,可以得出樓層 x,然後還有x-1次機會,第二扔完又沒爛,然後還有x-2次機會,這樣一推理,可以得到的樓層數為: x + (x - 1) + (x - 2) + … + 1 = x(x+1) / 2 >=100,解方程,求出x,即可。感覺這個例子可以幫助理解上面那個公式:dp[m][k] = dp[m - 1][k] + dp[m - 1][k - 1] + 1
class solution:
def supereggdrop(self, k, n): # 方法1
dp = [[0] * (k + 1) for i in range(n + 1)]
for m in range(1, n + 1):
for k in range(1, k + 1):
dp[m][k] = dp[m - 1][k - 1] + dp[m - 1][k] + 1
if dp[m][k] >= n:
return m
def supereggdrop1(self, k, n): # 方法2 + 空間優化
dp = [0] * (k + 1)
m = 0
while dp[k] < n:
for k in range(k, 0, -1):
dp[k] = dp[k - 1] + dp[k] + 1
m += 1
return m
if __name__ == '__main__':
solu = solution()
print(solu.supereggdrop(2, 100))
遞迴演算法心得
其實原理,老師也都講了,大家也都懂。我這裡說一些個人理解的技巧。其實遞迴主要是找到數字之間的規律,因此在寫遞迴體時,應該找出第n項與第 n 1 和 n 2 的關係,就可以列出遞迴體來。下面給大家個例子。1 計算n的階乘 如下 public class testrecursion else 2 乙個古...
演算法題心得
演算法題 1.有一頭母牛,它每年年初生一頭小母牛。每頭小母牛從第四個年頭開始,每年年初也生一頭小母牛。請程式設計實現在第n年的時候,共有多少頭母牛?input 輸入資料由多個測試例項組成,每個測試例項佔一行,包括乙個整數n 0 include intmain else sum o t s f pri...
學習演算法之心得
1 演算法,浩如煙海,找到自己感興趣的那個分支,或那個點來學習,然後,一往無前的深入 下去。2 興趣第一,一切,由著你的興趣走,忌浮躁。3 思維敏捷。給你一道常見的題目,你的頭腦中應該立刻能冒出解決這道問題的最適用的資料結構,以及演算法。4 隨興趣,多刷題。acm題。poj,面試題,包括下文將出現的...