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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态规划,从例子到理解

發(fā)布時(shí)間:2024/9/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态规划,从例子到理解 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

如何設(shè)計(jì)動(dòng)態(tài)規(guī)劃?

1、問題建模:得到優(yōu)化的目標(biāo)函數(shù),約束條件? 2、劃分子問題:明確問題的規(guī)模在哪里?哪些維度的規(guī)模,這樣才能才會劃分子問題,注意邊界。 3、得到遞推方程:可以宏觀的考慮,也可以借助于微觀的歸納演繹。 4、然后檢測是否滿足最優(yōu)子結(jié)構(gòu):檢查子問題對其子問題的始、終點(diǎn)也是最優(yōu)的序列。 5、最小問題的界定,確定初值。

如何編碼動(dòng)態(tài)規(guī)劃?

一般得到了遞推方程,就可以寫出基于遞歸的代碼實(shí)現(xiàn)。
假如子問題大量的重復(fù)計(jì)算,可借助于遞歸樹分析,就要考慮動(dòng)態(tài)規(guī)劃。
一般可基于兩種方式實(shí)現(xiàn)動(dòng)態(tài)規(guī)劃:一是基于自頂向下的備忘模型,二是基于自底向上演繹模型。

自頂向下的備忘模型:

1、標(biāo)記哪些子問題結(jié)果已經(jīng)計(jì)劃出來了沒,計(jì)算出來了就直接用, 2、特點(diǎn)是代碼簡單,可以直接基于遞歸的代碼修改,可能比自底向上演繹模型更節(jié)省運(yùn)算,因?yàn)闆]有用到的子問題沒有必要計(jì)算, 3、缺點(diǎn)是追蹤解可能需要專門設(shè)計(jì)或者不好實(shí)現(xiàn),自頂向下的備忘模型追蹤解我還要總結(jié)一番。

基于自底向上演繹模型:

1、從小到大的子問題依次計(jì)算; 2、前面的計(jì)算結(jié)果,后面會用到,所以備忘表格初值很重要; 3、類似于數(shù)學(xué)歸納法,從已知到未知,演繹推理; 4、演繹推理過程,可以標(biāo)記路徑,追蹤解比較容易實(shí)現(xiàn); 5、缺點(diǎn):并不是最大規(guī)模以下的所有子問題都需要計(jì)算。

偷金子,相鄰房間不能偷,如何價(jià)值最大?

#%% # house gold def house_gold_Rec(gold,n):if n == 0:return gold[0]if n == 1:return gold[gold[0]<gold[1]]first = gold[n]+house_gold_Rec(gold,n-2)second = house_gold_Rec(gold,n-1)return (first,second)[first<second]def house_gold_Top_down_(gold):n = len(gold)list = [-1]*(n)list[0] = gold[0]list[1] = gold[gold[0]<gold[1]]def house_gold_Top_down(gold,n):if list[n] == -1:first = gold[n]+house_gold_Top_down(gold,n-2)second = house_gold_Top_down(gold,n-1)list[n] = (first,second)[first<second]return list[n]return house_gold_Top_down(gold,n-1)def house_gold_Bottom_up(gold):n =len(gold)list= [gold[0],gold[gold[0]<gold[1]]]for i in range(2,n):first = gold[i]+list[i-2]second = list[i-1]list.append((first,second)[first<second])return list[n-1] #%% gold = [10,28,5,77,5,10,99,88,67] #%% print house_gold_Rec(gold,len(gold)-1) #%% print house_gold_Top_down_(gold) #%% print house_gold_Bottom_up(gold)

運(yùn)行結(jié)果

gold = [10,28,5,77,5,10,99,88,67]print house_gold_Rec(gold,len(gold)-1) 271print house_gold_Top_down_(gold) 271print house_gold_Bottom_up(gold) 271

換硬幣,使換的次數(shù)最少?

#%% #coin change def coins_change_Rec(money,coins):if money == 0:return 0result = 1000for i in range(len(coins)):if money >= coins[i]:first = coins_change_Rec(money-coins[i],coins)result = (first,result)[first>result] result += 1return resultdef coins_change_Top_down_(money,coins):list = [-1]*(money+1)list[0] =0def coins_change_Top_down(money,coins):result = 10000for i in range(len(coins)):if money >= coins[i]:if list[money-coins[i]] == -1:list[money-coins[i]] = coins_change_Top_down(money-coins[i],coins)result = (list[money-coins[i]],result)[list[money-coins[i]]>result]list[money] = result + 1return list[money]coins_change_Top_down(money,coins) print listreturn list[money]def coins_change_bottom_up(money,coins):list = [0,]min_ = min(coins)for x in range(1,min_):list.append(10000)list.append(1)for j in range(min_+1,money+1):result = 10000for i in range(len(coins)):if j >= coins[i]:result = (list[j-coins[i]],result)[list[j-coins[i]]>result]list.append(result +1)print listreturn list[money]

輸出結(jié)果

#%% coins = [13,11,19,23,29,66,46,90] money = 101 print coins_change_Rec(money,coins)print coins_change_Top_down_(money,coins) print coins_change_bottom_up(money,coins) 2 2 2

總結(jié)

以上是生活随笔為你收集整理的动态规划,从例子到理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。