python动态规划详解_python----动态规划
不能放棄治療,每天都要進步!!
什么時候使用動態規劃呢?
1. 求一個問題的最優解
2. 大問題可以分解為子問題,子問題還有重疊的更小的子問題
3. 整體問題最優解取決于子問題的最優解(狀態轉移方程)
4. 從上往下分析問題,從下往上解決問題
5. 討論底層的邊界問題
實例1:割繩子問題
題目:給你一根長度為n的繩子,請把繩子剪成m段 (m和n都是整數,n>1并且m>1)每段繩子的長度記為k[0],k[1],…,k[m]. 請問k[0]k[1]…*k[m]可能的最大乘積是多少?例如,當繩子的長度為8時,我們把它剪成長度分別為2,3,3的三段,此時得到的最大乘積是18.
思路:f(n)=max{f(i)f(n-i)},想發與實現是2個方法,想的時候是遞歸,實現的時候是從底層至最上面。
實現:1米最1,2米最大是2,3米最大是3,4米最大是4,依次類推,求n米的最大切割
算法復雜度O(n2)
#-*- coding: utf-8 -*
defmaxCutString(length):#這三行代表輸入的繩子長度為1,2,3時,發生切割動作,最大的乘積
if length < 2:return0if length == 2:return 1
if length == 3:return 2
#繩子不斷切割,當切割到長度為1,2,3時,不能繼續切割,直接返回1,2.3
arr=[0,1,2,3]#記錄繩子長度為i時候的最大乘積arr[i]
for i in range(4,length+1):
maxs=0for j in range(1,i/2+1):
mult=arr[j]*arr[i-j]if maxs
maxs=mult
arr.append(maxs)returnarr[length]print maxCutString(8)
View Code
實例2:最大連續子項和
思路:
實現:maxtmp記錄臨時子項和,遇到的每一個數不斷累加;當maxtmp為負時,清空,從下一個數開始,從新累加;當累加的數大于maxsum時,將值賦給maxsum
復雜度:O(n)
#-*- coding: utf-8 -*#!usr/bin/python
defmaxSum(lists):
maxsum=0
maxtmp=0for i inrange(len(lists)):if maxtmp<=0:
maxtmp=lists[i]else:
maxtmp+=lists[i]if maxtmp >maxsum:
maxsum=maxtmpreturnmaxsum
lists=[1,3,-3,4,-6,5]print maxSum(lists)
View Code
還有一種暴力求解,雙層遍歷,復雜度O(n2)
#-*- coding: utf-8 -*#!usr/bin/python
defmaxSum(lists):
maxsum=0for i inrange(len(lists)):
maxtmp=0for j inrange(i,len(lists)):
maxtmp+=lists[j]if maxtmp >maxsum:
maxsum=maxtmpreturnmaxsum
lists=[1,3,-3,4,-6,5]print maxSum(lists)
View Code
實例3:放蘋果
把M個同樣的蘋果放在N個同樣的盤子里,允許有的盤子空著不放,問共有多少種不同的分法?(用K表示)5,1,1和1,5,1 是同一種分法。
思路:f(m,n) =f(m,n-1)+f(m-n,n)
設f(m,n) 為m個蘋果,n個盤子的放法數目,則先對n作討論,
當n>m:必定有n-m個盤子永遠空著,去掉它們對擺放蘋果方法數目不產生影響。即if(n>m) f(m,n) = f(m,m)
當n<=m:不同的放法可以分成兩類:
1、有至少一個盤子空著,即相當于f(m,n) = f(m,n-1);
2、所有盤子都有蘋果,相當于可以從每個盤子中拿掉一個蘋果,不影響不同放法的數目,即f(m,n) = f(m-n,n).
而總的放蘋果的放法數目等于兩者的和,即 f(m,n) =f(m,n-1)+f(m-n,n)
遞歸出口條件說明:
1.當n=1時,所有蘋果都必須放在一個盤子里,所以返回1;
2.當沒有蘋果可放時,定義為1種放法;
遞歸的兩條路,第一條n會逐漸減少,終會到達出口n==1;
第二條m會逐漸減少,因為n>m時,我們會return f(m,m) 所以終會到達出口m==0
#!usr/bin/python
deff(m,n):if (m==0 or n==1):return 1
if m
lines=map(int,raw_input().strip().split())print f(lines[0],lines[1])
View Code
實例四:青蛙跳臺階問題
1.如果青蛙可以一次跳 1 級,也可以一次跳 2 級。問要跳上第 n級臺階有多少種跳法?
思路:f(n)=f(n-1)+f(n-2) 第n級別只能由n-1級別和第n-2級別的青蛙跳到
#-*- conding: utf-8 -*#遞歸解法
deff(n):if n==1:return 1
elif n==2:return 2
else:return f(n-1)+f(n-2)print f(8)#自下到上解法
deff2(n):
arr=[0,1,2]for i in range(3,n+1):
tmp=arr[i-1]+arr[i-2]
arr.append(tmp)returnarr[n]print f2(8)
View Code
2.如果青蛙可以一次跳 1 級,也可以一次跳 2 級,一次跳 3 級,…,一次跳 nn 級。問要跳上第 n級臺階有多少種跳法?
#.*. coding:utf-8 -*#遞歸解法
deff(n):if n==1:return 1
else:return 2*f(n-1)print f(8)#自下而上解法
deff2(n):
arr=[0,1,2]for i in range(3,n+1):
tmp=2*arr[i-1]
arr.append(tmp)returnarr[n]print f2(8)
View Code
總結
以上是生活随笔為你收集整理的python动态规划详解_python----动态规划的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android应用控制百度地图,Andr
- 下一篇: java反编译工具_JDA Java反编