動態規劃python

2021-09-25 16:00:48 字數 4755 閱讀 3646

問題描述:最長遞迴子串行即給定乙個序列,求解其中最長的遞增的子串行的長度

注意:在求解過程中,長度為n的遞增子串行可能不止乙個,但是在所有長度為n的子串行中,有乙個子串行是比較特殊的,那就是最大元素最小的遞增子序

def

getdp1

(arr)

: n=

len(arr)

dp=[0

]*nfor i in

range

(n):

dp[i]=1

for j in

range

(i):

if arr[i]

>arr[j]

: dp[i]

=max

(dp[i]

,dp[j]+1

)return dp

defgeneratelis

(arr,dp)

:#dp中存放以各元素為結尾元素時形成的遞增序列的最大長度

n=max(dp)

#陣列的最大值-整體的最大長度

index=dp.index(n)

#最大值下標,形成最長遞增子串行的結尾元素的下標

lis=[0

]*nn-=

1 lis[n]

=arr[index]

#定位序列中最後乙個元素

for i in

range

(index,-1

,-1)

:#從右向左

if arr[i]

and dp[i]

==dp[index]-1

: n-=

1 lis[n]

=arr[i]

index=i

return lis

arr=[2

,3,1

,4,5

,9,6

,0]dp=getdp1(arr)

result=generatelis(arr,dp)

print

(result)

時間複雜度為o(n*n),考慮使用二分查詢,降低複雜度為o(nlogn)

def

getdp2

(arr)

: n=

len(arr)

end,dp=[0

]*n,[0

]*nend[0]

,dp[0]

=arr[0]

,1l,r,right,m=0,

0,0,

0for i in

range(1

,n):

l=0 r=right

#二分查詢,若找不到則end[l或r]是比arr[i]大而又接近的數

#若arr[i]比ends有效區的值都大,則l=right+i

while l<=r:

m=(l+r)//2

if arr[i]

>end[m]

: l=m+

1else

: r=m-

1 right=

max(right,l)

end[l]

=arr[i]

dp[i]

=l+1

return dp

問題描述:求n個重量為w1,w2,…,wn、價值為v1,v2,…,vn的物品和乙個承重量為w的揹包,求讓包裡裝入的物品具有最大價值總合的物品子集。

def

map_record

(n,c,w,v)

:#初始化記錄表

record_map=[[

0for i in

range

(c+1)]

for i in

range

(len

(n)+1)

]for i in

range(1

,len

(n)+1)

:for j in

range(1

,c+1):

#應用狀態轉移函式填寫記錄表

if j: record_map[i]

[j]=record_map[i-1]

[j]else

: record_map[i]

[j]=

max(record_map[i-1]

[j],record_map[i-1]

[j-w[i-1]

]+v[i-1]

)return record_map

defshow

(n,c,w,res)

:print

('最大價值為:'

,res[

len(n)

][c]

) x=

[false

for i in

range

(len

(n)+1)

] j=c

i=len(n)

#回溯while i>=0:

if res[i]

[j]>res[i-1]

[j]:

x[i]

=true

j-=w[i-1]

i-=1print

('選擇的物品為:'

)for i in

range

(len

(n)+1)

:if x[i]

:print

('第'

,i,'個,'

,end='')

print(''

)n=['a'

,'b'

,'c'

,'d']c=

8w=[2

,4,5

,3]v=

[5,4

,6,2

]res=map_record(n,c,w,v)

show(n,c,w,res)

問題描述:某一地區發現了5座金礦,每座金礦的**儲量不同,需要參與挖掘的工人數也不同,假設參與挖礦工人的總數是10人,且每座礦要麼全挖,要麼不挖,不能派出一半人挖取一半金礦。要求用程式求解,要想盡可能得到多的**,應該選擇挖取哪幾座金礦?

def

goldmining

(n,w,g,p)

: results=

#儲存返回結果的陣列

preresults=

#儲存上一行結果的陣列0)

#陣列第一位為輔助位,填充為00)

for i in

range(1

,w+1):

#從左到右填充**第一行的內容,填充邊界格仔的值0)

#初始化結果陣列

if i:#人數少於第乙個金礦所需人數,**量為00)

else

:#否則,**量為第乙個金礦儲量0]

) results[i]

=preresults[i]

for i in

range(1

,n):

#外層為金礦數量

for j in

range(1

,w+1):

#內層為礦工數量(注意下標)

if j: results[j]

=preresults[j]

else

: results[j]

=max

(preresults[j]

,preresults[j-p[i]

]+g[i]

) preresults=results.copy(

)del results[0]

return resultsn=5

w=10g=[

400,

500,

200,

300,

350]p=[

5,5,

3,4,

3]result=goldmining(n,w,g,p)

print

(result)

該問題解決思路和揹包問題一致,但注意兩者在處理第一行資料的不同之處

問題描述:小明家住在二樓,每次回家都需要經過乙個有10層臺的樓梯。小明每次選擇可以走一級台階或二級台階。請幫助小明算算他從樓下到家一共有多少種走法。

dp=getdp(arr)

result=generatelis(arr,dp)

print

(result)

defupstairs

(n):

a=1 b=

2 temp=

0if n<1:

print(0

)if n==1:

print(1

)if n==2:

print(2

)for i in

range(3

,n+1):

#迭代求解各級台階的走法

temp=a+b

a=bb=temp

print

(temp)

upstairs(

3)

python動態規劃

思路 把每次的結果放在字典裡 from functools import wraps defmemo func cache wraps func defwrap args if args not in cache cache args func args return cache args retu...

動態規劃python實現

考慮乙個場景 當你有去沙漠旅行,你有乙個揹包和一些物品,揹包有最大承受重量,物品也有重量和價值,而物品種類很多,不可能全都裝在揹包裡,如何去選取價值總量最高的物品組合呢?物品名價值 water 10book 3food 9jacket 5camera 6物品名 重量water 3kgbook 1kg...

python學習動態規劃

今天花了幾個小時,重新理解了一下dp。首先我們要知道為什麼要使用dp,我們在選擇dp演算法的時候,往往是在決策問題上,而且是在如果不使用dp,直接暴力效率會很低的情況下選擇使用dp.那麼問題來了,什麼時候會選擇使用dp呢,一般情況下,我們能將問題抽象出來,並且問題滿足無後效性,滿足最優子結構,並且能...