贪心算法数塔问题c语言,c语言背包问题_c语言背包问题几种解法_背包问题贪心算法(2)...
(3).動(dòng)態(tài)規(guī)劃(Dynamic Programming,以下簡(jiǎn)稱DP)
俗話說(shuō),要看一個(gè)人的算法水平,只要看一下他做DP題的水平就OK了,而在ACM這個(gè)多變的賽場(chǎng)上,幾多算法沉浮,唯有DP幾乎從未消失過(guò),如果你問(wèn)我什么類(lèi)型的題在賽場(chǎng)上出現(xiàn)的概率最高,我可以毫不猶豫地告訴你,是DP。由此也可以看出,DP的地位有多么重要,那么這樣一個(gè)幾乎每場(chǎng)比賽都會(huì)出現(xiàn)的題型,應(yīng)該很難啊,為什么要讓我們從DP入手呢?確實(shí),DP是很難,其變型之多,覆蓋知識(shí)面之廣,確實(shí)讓人望而生卻,但是,我想說(shuō)下如何入門(mén)DP題。首先是DP幾個(gè)最為基本的模型,LCS(最長(zhǎng)公共子序列),LIS(最長(zhǎng)上升子序列),最大公共子段和,數(shù)塔問(wèn)題,矩陣連乘等幾個(gè)最為經(jīng)典的問(wèn)題,大家一開(kāi)始的時(shí)候可能難以理解DP中自底向上,重疊子結(jié)構(gòu)等基本思想,對(duì)于這幾道問(wèn)題可以先看一下別人的代碼和書(shū)上的講解,然后再自己反復(fù)地理解,理解了之后再自己敲一下代碼,如果有地方實(shí)在不理解,可以先放一下,去看看其他題,回過(guò)頭來(lái)再想一下以前的題,也許會(huì)有豁然開(kāi)朗的效果。吃透了DP的幾個(gè)經(jīng)典問(wèn)題之后,就可以做一下這些經(jīng)典問(wèn)題的變型了,比如最大公共子段和的變型——最大子矩陣和最大m子段和,最長(zhǎng)公共子序列和最長(zhǎng)上升子序列的變型——最長(zhǎng)公共上升子序列等等。并且可以嘗試接觸DP的一些重要的應(yīng)用,最重要的要數(shù)背包問(wèn)題,背包問(wèn)題是DP一個(gè)很大的分支(算是分支吧,我找不到其他更好的詞來(lái)形容他了),同樣也有非常多的變型,如最為基礎(chǔ)的01背包,以及擴(kuò)充出去的多重背包,完全背包,分組背包,樹(shù)型DP(這個(gè)知識(shí)點(diǎn)我待會(huì)會(huì)介紹)中應(yīng)用非常多的泛化背包等等,下面我把最為基本01背包,多重背包和完全背包講一下,首先是最簡(jiǎn)單的01背包,偽代碼如下:
for i=1..N
for v=V..0
f[v]=max{ f[v], f[ v-c[i] ] + w[i] }
這里為什么要倒推呢?其實(shí)道理很簡(jiǎn)單,因?yàn)檫@里其實(shí)是利用類(lèi)似滾動(dòng)數(shù)組的概念,只不過(guò)他連2個(gè)數(shù)組都不用開(kāi)了,只需要開(kāi)一個(gè)數(shù)組就可以了,這是為什么呢?因?yàn)閭鹘y(tǒng)的二維數(shù)組中f[i][v]的值是由max( f[i-1][v], f[i-1][ v-c[i] ] + w[i] )得來(lái)的,所以每次f[v]的值是由上層循環(huán)中fv’得來(lái)的,所以改成了一維數(shù)組后,如果從小到大循環(huán)的話,在計(jì)算完成f[v] 之后,就會(huì)在計(jì)算f[v’](v’ >=v)時(shí)發(fā)生錯(cuò)誤,因?yàn)樵居?jì)算f[v’]所需的上層循環(huán)中的f[v]的值已經(jīng)被新的值覆蓋掉了,故必須從大到小循環(huán)。其次是多重背包,完全可以化為01背包問(wèn)題,不過(guò)是把相同價(jià)值的同種類(lèi)物品看成多個(gè)價(jià)值相同的不同種類(lèi)物品,即比01背包多了一重循環(huán),要注意的是這兩層循環(huán)都要從大到小,原理和01背包類(lèi)似。最后是完全背包問(wèn)題,偽代碼如下:
for i=1..N
for v=0..V
f[v]=max{ f[v], f[ v-c[i] ] + w[i] }
這個(gè)偽代碼與01背包的偽代碼只有v的循環(huán)次序不同而已。為什么這樣一改就可行呢?首先想想為什么01背包中要按照v=V..0的逆序來(lái)循環(huán)。這是因?yàn)橐WC第i次循環(huán)中的狀態(tài)f[i][v]是由狀態(tài)f[i-1][v-c[i]]遞推而來(lái)。換句話說(shuō),這正是為了保證每件物品只選一次,保證在考慮“選入第i件物品”這件策略時(shí),依據(jù)的是一個(gè)絕無(wú)已經(jīng)選入第i件物品的子結(jié)果f[i-1][v-c[i]]。而現(xiàn)在完全背包的特點(diǎn)恰是每種物品可選無(wú)限件,所以在考慮 “加選一件第i種物品”這種策略時(shí),卻正需要一個(gè)可能已選入第i種物品的子結(jié)果f[i][v-c[i]],所以就可以并且必須采用v= 0..V的順序循環(huán)。這就是這個(gè)簡(jiǎn)單的程序?yàn)楹纬闪⒌牡览怼_@里我向大家推薦一下浙江大學(xué)的DD牛所寫(xiě)的《背包九講》,是背包入門(mén)及提高的最為經(jīng)典的資料。現(xiàn)在就要講一下樹(shù)型DP了,樹(shù)型DP其實(shí)就是DP,只不過(guò)是建立在樹(shù)模型之上的DP罷了,不過(guò)樹(shù)型DP說(shuō)起來(lái)雖然簡(jiǎn)單,確是DP中相當(dāng)困難的一個(gè)知識(shí)點(diǎn),要好好理解,多做些題才行。最后是狀態(tài)壓縮DP,這也是一個(gè)DP的一個(gè)難點(diǎn),所謂的狀態(tài)是指利用二進(jìn)制或者其他進(jìn)制的數(shù)來(lái)表示狀態(tài)從而達(dá)到空間上壓縮的目的,這一類(lèi)的狀態(tài)設(shè)計(jì)一般都很巧妙,而且涉及的眾多位運(yùn)算對(duì)于編碼能力也是一個(gè)相當(dāng)大的挑戰(zhàn),介于狀態(tài)壓縮DP是用記憶化搜索(所謂記憶化搜索,是DP的另外一種遞歸的實(shí)現(xiàn)形式,即所謂的自頂向下)來(lái)實(shí)現(xiàn)的,又要牽涉到搜索的知識(shí)點(diǎn),建議等學(xué)習(xí)了相關(guān)的內(nèi)容之后再回過(guò)來(lái)頭來(lái)學(xué)習(xí)這個(gè)知識(shí)點(diǎn)。狀態(tài)壓縮的經(jīng)典題有棋盤(pán)覆蓋問(wèn)題,炮兵陣地等。
本文來(lái)自電腦雜談,轉(zhuǎn)載請(qǐng)注明本文網(wǎng)址:
http://www.pc-fly.com/a/tongxinshuyu/article-24376-2.html
總結(jié)
以上是生活随笔為你收集整理的贪心算法数塔问题c语言,c语言背包问题_c语言背包问题几种解法_背包问题贪心算法(2)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux ll命令无效
- 下一篇: 第六十一期: 从7600万个5G连接中,