動態規劃(自底向上)
阿新 • • 發佈:2018-12-31
1. 動態規劃 備忘錄法
備忘錄方法採用自頂向下方式,為每個解過的子問題建立了備忘錄以備需要時檢視,避免了相同子問題的重複求解。
說明: 在非邊界條件下,每次求解子問題時,先查詢備忘錄.
若子問題已經求解過了,直接取出子問題的解;若未求解過,則求解並儲存到備忘錄中.
此處的備忘錄就是一個儲存資料的容器.
Java程式碼- /*
- @author: jarg
- @TODO 動態規劃 - 備忘錄法 求解二項式係數
- */
- /* 求解二項式係數 */
- publicstaticint Binomial(int n,int m)
- {
- /* 邊界條件 */
- if(n==m || m==0)
- {
- return1;
- }
- int date = readDate(n,m);
- if(date>0)
- {
- /*
- 子問題已經計算過
- 讀取儲存在備忘錄中的資料
- */
- return date;
- }
- else
- {
- /*
- 子問題未計算過
- 解出子問題,將資料儲存在備忘錄中
- */
- int result = Binomial(n-1,m) + Binomial(n-1,m-1);
- writeDate(n,m,result);
- return result;
- }
- }
- /* 從備忘錄中讀取資料 */
- publicstaticint readDate(int n,int m)
- {
- for(int i=0;i<demo.size();i++)
- {
- Map<String,Integer> date = new
- date = demo.get(i);
- if(date.get("" + n + m) !=null)
- {
- return date.get("" + n + m);
- }
- }
- return0;
- }
- /* 向備忘錄中寫入資料 */
- publicstaticvoid writeDate(int n,int m,int value)
- {
- Map<String,Integer> date = new HashMap<String,Integer>();
- date.put("" + n + m,value);
- demo.add(date);
- }
/*
@author: jarg
@TODO 動態規劃 - 備忘錄法 求解二項式係數
*/
/* 求解二項式係數 */
public static int Binomial(int n,int m)
{
/* 邊界條件 */
if(n==m || m==0)
{
return 1;
}
int date = readDate(n,m);
if(date>0)
{
/*
子問題已經計算過
讀取儲存在備忘錄中的資料
*/
return date;
}
else
{
/*
子問題未計算過
解出子問題,將資料儲存在備忘錄中
*/
int result = Binomial(n-1,m) + Binomial(n-1,m-1);
writeDate(n,m,result);
return result;
}
}
/* 從備忘錄中讀取資料 */
public static int readDate(int n,int m)
{
for(int i=0;i<demo.size();i++)
{
Map<String,Integer> date = new HashMap<String,Integer>();
date = demo.get(i);
if(date.get("" + n + m) != null)
{
return date.get("" + n + m);
}
}
return 0;
}
/* 向備忘錄中寫入資料 */
public static void writeDate(int n,int m,int value)
{
Map<String,Integer> date = new HashMap<String,Integer>();
date.put("" + n + m,value);
demo.add(date);
}
2. 動態規劃 迭代法:
迭代法採用自底向上方式,儲存已求解的子問題,需要時取出,消除對某些子問題的重複求解.
Pascal三角形:
說明: 在非邊界的情況下,二項式係數=上一行同列數值+上一行同列前一個數值.
為了節省空間,根據n的大小,定義長度為n+1的整型陣列,用以儲存子問題的解.
從後往前計算圖中二項式係數的解,完成後,將問題解儲存在陣列中對應的列標號位置.
Java程式碼- /*
- @author: jarg
- @TODO: 動態規劃 - 求解二項式係數
- */
- /* 求二項式係數 */
- publicstaticint binomial(int n,int m)
- {
- int value[] = newint[n+1];
- for(int i=0;i<=n;i++)
- {
- value[i] = 1;
- /* 邊界條件m=0,n=m的情況 */
- for(int j=i-1;j>0;j--)
- {
- value[j] = value[j] + value[j-1];
- }
- }
- return value[m];
- }