1. 程式人生 > >動態規劃(自底向上)

動態規劃(自底向上)


1. 動態規劃 備忘錄法

備忘錄方法採用自頂向下方式,為每個解過的子問題建立了備忘錄以備需要時檢視,避免了相同子問題的重複求解。

說明: 在非邊界條件下,每次求解子問題時,先查詢備忘錄.

若子問題已經求解過了,直接取出子問題的解;若未求解過,則求解並儲存到備忘錄中.

此處的備忘錄就是一個儲存資料的容器.

Java程式碼 複製程式碼 收藏程式碼
  1. /*
  2. @author: jarg
  3. @TODO 動態規劃 - 備忘錄法 求解二項式係數
  4. */
  5. /* 求解二項式係數 */
  6. publicstaticint Binomial(int n,int m)
  7. {
  8. /* 邊界條件 */
  9. if(n==m || m==0)
  10. {
  11. return1;
  12. }
  13. int date = readDate(n,m);
  14. if(date>0)
  15. {
  16. /*
  17. 子問題已經計算過
  18. 讀取儲存在備忘錄中的資料
  19. */
  20. return date;
  21. }
  22. else
  23. {
  24. /*
  25. 子問題未計算過
  26. 解出子問題,將資料儲存在備忘錄中
  27. */
  28. int result = Binomial(n-1,m) + Binomial(n-1,m-1);
  29. writeDate(n,m,result);
  30. return result;
  31. }
  32. }
  33. /* 從備忘錄中讀取資料 */
  34. publicstaticint readDate(int n,int m)
  35. {
  36. for(int i=0;i<demo.size();i++)
  37. {
  38. Map<String,Integer> date = new
    HashMap<String,Integer>();
  39. date = demo.get(i);
  40. if(date.get("" + n + m) !=null)
  41. {
  42. return date.get("" + n + m);
  43. }
  44. }
  45. return0;
  46. }
  47. /* 向備忘錄中寫入資料 */
  48. publicstaticvoid writeDate(int n,int m,int value)
  49. {
  50. Map<String,Integer> date = new HashMap<String,Integer>();
  51. date.put("" + n + m,value);
  52. demo.add(date);
  53. }
/*
@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程式碼 複製程式碼 收藏程式碼
  1. /*
  2. @author: jarg
  3. @TODO: 動態規劃 - 求解二項式係數
  4. */
  5. /* 求二項式係數 */
  6. publicstaticint binomial(int n,int m)
  7. {
  8. int value[] = newint[n+1];
  9. for(int i=0;i<=n;i++)
  10. {
  11. value[i] = 1;
  12. /* 邊界條件m=0,n=m的情況 */
  13. for(int j=i-1;j>0;j--)
  14. {
  15. value[j] = value[j] + value[j-1];
  16. }
  17. }
  18. return value[m];
  19. }