动态规划算法入门---java版
轉(zhuǎn)載:http://blog.csdn.net/p10010/article/details/50196211
?動(dòng)態(tài)規(guī)劃算法(后附常見(jiàn)動(dòng)態(tài)規(guī)劃為題及Java代碼實(shí)現(xiàn))
一、基本概念
?? ?動(dòng)態(tài)規(guī)劃過(guò)程是:每次決策依賴于當(dāng)前狀態(tài),又隨即引起狀態(tài)的轉(zhuǎn)移。一個(gè)決策序列就是在變化的狀態(tài)中產(chǎn)生出來(lái)的,所以,這種多階段最優(yōu)化決策解決問(wèn)題的過(guò)程就稱(chēng)為動(dòng)態(tài)規(guī)劃。
二、基本思想與策略
?? ?基本思想與分治法類(lèi)似,也是將待求解的問(wèn)題分解為若干個(gè)子問(wèn)題(階段),按順序求解子階段,前一子問(wèn)題的解,為后一子問(wèn)題的求解提供了有用的信息。在求解任一子問(wèn)題時(shí),列出各種可能的局部解,通過(guò)決策保留那些有可能達(dá)到最優(yōu)的局部解,丟棄其他局部解。依次解決各子問(wèn)題,最后一個(gè)子問(wèn)題就是初始問(wèn)題的解。
?? ?由于動(dòng)態(tài)規(guī)劃解決的問(wèn)題多數(shù)有重疊子問(wèn)題這個(gè)特點(diǎn),為減少重復(fù)計(jì)算,對(duì)每一個(gè)子問(wèn)題只解一次,將其不同階段的不同狀態(tài)保存在一個(gè)二維數(shù)組中。
?? ?與分治法最大的差別是:適合于用動(dòng)態(tài)規(guī)劃法求解的問(wèn)題,經(jīng)分解后得到的子問(wèn)題往往不是互相獨(dú)立的(即下一個(gè)子階段的求解是建立在上一個(gè)子階段的解的基礎(chǔ)上,進(jìn)行進(jìn)一步的求解)。
以上都過(guò)于理論,還是看看常見(jiàn)的動(dòng)態(tài)規(guī)劃問(wèn)題吧!!!
三、常見(jiàn)動(dòng)態(tài)規(guī)劃問(wèn)題
?? 1、找零錢(qián)問(wèn)題
?? 有數(shù)組penny,penny中所有的值都為正數(shù)且不重復(fù)。每個(gè)值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,再給定一個(gè)整數(shù)aim(小于等于1000)代表要找的錢(qián)數(shù),求換錢(qián)有多少種方法。
給定數(shù)組penny及它的大小(小于等于50),同時(shí)給定一個(gè)整數(shù)aim,請(qǐng)返回有多少種方法可以湊成aim。
測(cè)試樣例:
[1,2,4],3,3
返回:2
解析:設(shè)dp[n][m]為使用前n中貨幣湊成的m的種數(shù),那么就會(huì)有兩種情況:
???????????? 使用第n種貨幣:dp[n-1][m]+dp[n-1][m-peney[n]]
????????????? 不用第n種貨幣:dp[n-1][m],為什么不使用第n種貨幣呢,因?yàn)閜enney[n]>m。
??????? 這樣就可以求出當(dāng)m>=penney[n]時(shí) dp[n][m] = dp[n-1][m]+dp[n-1][m-peney[n]],否則,dp[n][m] = dp[n-1][m]
代碼如下:
[java]?view plaincopy
2、走方格問(wèn)題
? 有一個(gè)矩陣map,它每個(gè)格子有一個(gè)權(quán)值。從左上角的格子開(kāi)始每次只能向右或者向下走,最后到達(dá)右下角的位置,路徑上所有的數(shù)字累加起來(lái)就是路徑和,返回所有的路徑中最小的路徑和。
給定一個(gè)矩陣map及它的行數(shù)n和列數(shù)m,請(qǐng)返回最小路徑和。保證行列數(shù)均小于等于100.
測(cè)試樣例:
[[1,2,3],[1,1,1]],2,3
返回:4
解析:設(shè)dp[n][m]為走到n*m位置的路徑長(zhǎng)度,那么顯而易見(jiàn)dp[n][m] = min(dp[n-1][m],dp[n][m-1]);
?
代碼如下:
[java]?view plaincopy
3、走臺(tái)階問(wèn)題
有n級(jí)臺(tái)階,一個(gè)人每次上一級(jí)或者兩級(jí),問(wèn)有多少種走完n級(jí)臺(tái)階的方法。為了防止溢出,請(qǐng)將結(jié)果Mod 1000000007
給定一個(gè)正整數(shù)int n,請(qǐng)返回一個(gè)數(shù),代表上樓的方式數(shù)。保證n小于等于100000。
測(cè)試樣例:
1
返回:1
解析:
這個(gè)問(wèn)題典型的斐波那契數(shù)列問(wèn)題。
假設(shè)N級(jí)樓梯的爬法有A(N)種方法,假設(shè)第一步上一個(gè)臺(tái)階,則上法有A(N-1)種,如果第一步上兩個(gè)臺(tái)階,則上法有A(N-2)種方法,因此:
A(N)=A(N-1)+A(N-2)
而A(1)=1,A(2)=2,則A(3)=A(1)+A(2)=3,A(4)=A(2)+A(3)=5,……
從而可以遞推出N階臺(tái)階時(shí)的方法。
這是一個(gè)非常經(jīng)典的為題,設(shè)f(n)為上n級(jí)臺(tái)階的方法,要上到n級(jí)臺(tái)階的最后一步有兩種方式:從n-1級(jí)臺(tái)階走一步;從n-1級(jí)臺(tái)階走兩步,于是就有了這個(gè)公式f(n) = f(n-1)+f(n-2);
代碼如下:
[java]?view plaincopy
4、最長(zhǎng)公共序列數(shù)
給定兩個(gè)字符串A和B,返回兩個(gè)字符串的最長(zhǎng)公共子序列的長(zhǎng)度。例如,A="1A2C3D4B56”,B="B1D23CA45B6A”,”123456"或者"12C4B6"都是最長(zhǎng)公共子序列。
給定兩個(gè)字符串A和B,同時(shí)給定兩個(gè)串的長(zhǎng)度n和m,請(qǐng)返回最長(zhǎng)公共子序列的長(zhǎng)度。保證兩串長(zhǎng)度均小于等于300。
測(cè)試樣例:
"1A2C3D4B56",10,"B1D23CA45B6A",12
返回:6
解析:設(shè)dp[n][m] ,為A的前n個(gè)字符與B的前m個(gè)字符的公共序列長(zhǎng)度,則當(dāng)A[n]==B[m]的時(shí)候,dp[i][j] = max(dp[i-1][j-1]+1,dp[i-1][j],dp[i][j-1]),否則,dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
代碼如下:
[java]?view plaincopy總結(jié)
以上是生活随笔為你收集整理的动态规划算法入门---java版的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 二叉树的遍历java版本
- 下一篇: java知识百科全书--强烈推荐