假設有25分、20分、5分、1分的硬幣,現要找給客戶41分的零錢,如何辦到硬幣個數最少?
此前用貪心策略得到的並非是最優解(貪心得到的解是 5 枚硬幣)
假設 dp(n) 是湊到 n 分需要的最少硬幣個數
①、如果第 1 次選擇了 25 分的硬幣,那麼 dp(n) = dp(n – 25) + 1
②、如果第 1 次選擇了 20 分的硬幣,那麼 dp(n) = dp(n – 20) + 1
③、如果第 1 次選擇了 5 分的硬幣,那麼 dp(n) = dp(n – 5) + 1
④、如果第 1 次選擇了 1 分的硬幣,那麼 dp(n) = dp(n – 1) + 1
所以 dp(n) = min + 1
public
class
coinchange
/*暴力遞迴(自頂向下的呼叫,出現了重疊子問題)*/
static
intcoins
(int n)
}
public
class
coinchange
/*記憶化搜尋(自頂向下的呼叫)*/
static
intcoins2
(int n)
;for
(int face : faces)
return
coins2
(n,dp);}
static
intcoins2
(int n,
int[
] dp)
return dp[n];}
}
public
class
coinchange
/*遞推(自底向上)*/
static
intcoins3
(int n)
return dp[n];}
}
public
class
coinchange
/*具體是用了哪些面值的硬幣*/
static
intcoins4
(int n)
if(i >=
5&& dp[i-5]
< min)
if(i >=
20&& dp[i-20]
< min)
if(i >=
25&& dp[i-25]
< min)
dp[i]
= min +1;
//print(faces,i);
}print
(faces,n)
;return dp[n];}
static
void
print
(int
faces,
int n)
system.out.
println()
;}}執行結果:[41
]=120
203----
----
------[
19]=1
1115557
public
class
coinchange))
;//3
}static
intcoins5
(int n,
int[
] faces)
+ 1 ->求用到硬幣數量最少的個數
} dp[i]
= min +1;
}return dp[n];}
}
public
class
coinchange))
;//3
system.out.
println
(coins5(6
,new
int)
);//-1
}static
intcoins5
(int n,
int[
] faces)
if(min == integer.max_value)
else
}return dp[n];}
}
動態規劃 什麼是動態規劃?
先來看看 資訊學奧賽一本通第5版 是怎麼說的 動態規劃程式設計是對解最優化問題的一種途徑 一種方法,而不是一種特殊演算法。不像前面所述的那些搜尋或數值計算那樣,具有乙個標準的數學表示式和明確清晰的解題方法。動態規劃程式設計往往是針對一種最優化問題,由於各種問題的性質不同,確定最優解的條件也互不相同,...
mysql動態規劃 動態規劃
動態規劃 能夠動態規劃的問題具有以下特點 可分解成規模更小的子問題 子問題的結果可復用 關鍵是要理解狀態轉移方程的含義就好啦!數字三角形 問題描述 在數字三角形尋找從頂到底的路徑,使得路徑經過的數字之和最大。規定每一步只能往左下或右下走,求出最大路徑和。遞迴解法 include include us...
《動態規劃》 ACM 動態規劃例題詳解
描述 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 圖1 圖1給出了乙個數字三角形。從三角形的頂部到底部有很多條不同的路徑。對於每條路徑,把路徑上面的數加起來可以得到乙個和,你的任務就是找到最大的和。注意 路徑上的每一步只能從乙個數走到下一層上和它最近的左邊的那個數或者右邊的那個數。輸...