日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

简单暴力到dp的优化(萌新篇)

發布時間:2023/12/13 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单暴力到dp的优化(萌新篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

想寫一系列文章,總結一些題目,看看解決問題、優化方法的過程到底是什么樣子的。

?

系列問題一:斐波那契數列問題

在數學上,斐波納契數列以如下被以遞歸的方法定義:F(0)=0,F(1)=1, F(n)=F(n-1)+F(n-2)(n>=2,n∈N*)根據定義,前十項為1, 1, 2, 3, 5, 8, 13, 21, 34, 55

問題一:

給定一個正整數n,求出斐波那契數列第n項(這時n較小)

解法一:最笨,效率最低,暴力遞歸,完全是抄定義。請看代碼

def f0(n):if n==1 or n==2:return 1return f(n-1)+f(n-2)

?

分析一下,為什么說遞歸效率很低呢?咱們來試著運行一下就知道了:

?

比如想求f(10),計算機里怎么運行的?

?

每次要計算的函數量都是指數型增長,時間復雜度O(2^(N/2))<=T(N)<=O(2^N),效率很低。效率低的原因是,進行了大量重復計算,比如圖中的f(8),f(7).....等等,你會發現f(8)其實早就算過了,但是你后來又要算一遍。

如果我們把計算的結果全都保存下來,按照一定的順序推出n項,就可以提升效率, 斐波那契(所有的一維)的順序已經很明顯了,就是依次往下求。。

優化1

def f1(n):if n==1 or n==2:return 1l=[0]*nl[0],l[1]=1,1for i in range(2,n):l[i]=l[i-1]+l[i-2]return l[-1]

?

時間復雜度o(n),依次往下打表就行,空間o(n).

繼續優化:既然只求第n項,而斐波那契又嚴格依賴前兩項,那我們何必記錄那么多值呢?記錄前兩項就行了

?

優化2

def f2(n):a,b=1,1for i in range(n-1):a,b=b,a+breturn a

此次優化做到了時間o(n),空間o(1)

附:這道題掌握到這里就可以了,但是其實有時間o(log2n)的方法

?

優化三:

學習過線性代數的同學們能夠理解:

?

結合快速冪算法,我們可以在o(log2n)內求出某個對象的n次冪。(在其它專題詳細講解)

注意:只有遞歸式不變,才可以用矩陣+快速冪的方法。

注:優化三可能只有在面試上或競賽中用,當然,快速冪還是要掌握的。

?

經過這個最簡單的斐波那契,大家有沒有一點感覺了?

好,我們繼續往下走

(補充:pat、藍橋杯原題,讓求到一萬多位,結果模一個數。

可以每個結果都對這個數取模,否則爆內存,另:對于有多組輸入并且所求結果類似的題,可以先求出所有結果存起來,然后直接接受每一個元素,在表中查找相應答案)

?

問題二:

一只青蛙一次可以跳上1級臺階,也可以跳上2級。求該青蛙跳上一個n級的臺階總共有多少種跳法。

依舊是找遞推關系,分析:跳一階,就一種方法,跳兩階,它可以一次跳兩個,也可以一個一個跳,所以有兩種,三個及三個以上,假設為n階,青蛙可以是跳一階來到這里,或者跳兩階來到這里,只有這兩種方法。它跳一階來到這里,說明它上一次跳到n-1階,同理,它也可以從n-2跳過來,f(n)為跳到n的方法數,所以,f(n)=f(n-1)+f(n-2)

和上題的優化二類似。

因為遞推式沒變過,所以可以用優化三

?

問題三:

我們可以用2*1的小矩形橫著或者豎著去覆蓋更大的矩形。請問用n個2*1的小矩形無重疊地覆蓋一個2*n的大矩形,總共有多少種方法?提示,大矩形看做是長度吧

請讀者自己先思考一下吧。。。仔細看題。。仔細思考

如果n是1,只有一種,豎著放唄;n是2,兩種:

n等于3,三種:

?

題意應該理解了吧?

讀到這里,你們應該能很快想到,依舊是斐波那契式遞歸啊。

對于n>=3:怎么能覆蓋到三?只有兩種辦法,從n-1的地方豎著放了一塊,或者從n-2的位置橫著放了兩塊唄。

和問題二的代碼都不用變。

?

問題四:

給定一個由0-9組成的字符串,1可以轉化成A,2可以轉化成B。依此類推。。25可以轉化成Y,26可以轉化成z,給一個字符串,返回能轉化的字母串的有幾種?

比如:123,可以轉化成

1 2 3變成ABC,

12 3變成LC,

1 23變成AW,三種,返回三,

99999,就一種:iiiii,返回一。

分析:求i位置及之前字符能轉化多少種。

兩種轉化方法,一,字符i自己轉換成自己對應的字母,二,和前面那個數組成兩位數,然后轉換成對應的字母

假設遍歷到i位置,判斷i-1位置和i位置組成的兩位數是否大于26,大于就沒有第二種方法,f(i)=f(i-1),想反,等于f(i-1)+f(i-2)

注意:遞歸式不確定,不能用矩陣快速冪

?

(這幾個題放到這里就是為了鍛煉找遞歸關系的能力,不要只會那個爛大街的斐波那契)

?

''' 斐波那契問題: 斐波納契數列以如下被以遞歸的方法定義: F(1)=1 F(2)=1 F(n)=F(n-1)+F(n-2)(n>=2,n∈N*) ''' #暴力抄定義,過多重復計算 def f0(n):if n==1 or n==2:return 1return f(n-1)+f(n-2) #記錄結果后依次遞推的優化,時間O(N) def f1(n):if n==1 or n==2:return 1l=[0]*nl[0],l[1]=1,1for i in range(2,n):l[i]=l[i-1]+l[i-2]return l[-1] #既然嚴格依賴前兩項,不必記錄每一個結果,優化空間到O(1) def f2(n):a,b=1,1for i in range(n-1):a,b=b,a+breturn a

?

總結

以上是生活随笔為你收集整理的简单暴力到dp的优化(萌新篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。