動態規劃:核心思想,找到最優子結構,組合子問題構成原問題的解。
最重要的是,找到最優子結構,這是最難的部分
例題:我們有面值為1元3元5元的硬幣若干枚,如何用最少的硬幣湊夠11元?
首先找到問題的子結構
1: 選擇硬幣作為子結構變數,
第一次選擇只有1元硬幣,求出構成11元硬幣的方案集合a1,第二次選擇有1,3元硬幣,求出構成11元硬幣的方案集合a2。第二次選擇有1,3,5元硬幣,求出構成11元硬幣的方案集合a3。那麼a1一定是a2的子集。a2一定是a3的子集。
從a3中選出使用最少硬幣個數的方案就是最優方案。
步驟一:
首先建乙個二維表x:
行代表能使用的硬幣,用i表示int coins=,列代表該列的總錢數,用j表示。
例如 x[1][5] 代表 硬幣能使用coins[0],coins[1] 總錢數為5時,所需要的最小硬幣個數。
只能使用1元硬幣構成11元,求出個數,
使用1,3元硬幣構成11元,求出使用的硬幣個數 。當選擇1,3元硬幣時,可以利用只用1元硬幣求出的最優解。
圖中x[i][j]該如何求得,
a : 當總錢數小於新加入的硬幣面值時,說明不能用新硬幣。只能用之前的硬幣求得的個數。
x[i][j]=x[i-1][j];
b: 當錢數大於等於新加入的硬幣面值時,說明可以使用新硬幣了
b.1:如果使用新硬幣,那麼新硬幣個數為1, 錢數為coins[i], 所以使用新硬幣之後的個數為x[i][j]=x[i][j-coins[i]]+1;
b.2: 如果使用新硬幣, 那麼需要的硬幣個數為 x[i][j]=x[i-1][j] 。
相比, 取較小的值。即為該錢數的情況下,使用的最小硬幣個數。
x[i][j]= min
得到結果x[1][3]=min =x[1][0]+1 =1 ;
選擇1,3,5元硬幣構成11元硬幣的,求出使用的硬幣個數
最終的結果:使用的硬幣為1,3,5。總錢數為11的值。
直接取出 x[2][11]即可。即為使用硬幣的最小個數。
**:
public2:選擇 總錢數作為 子結構變數。static
void
selectcoinasvariable() ;
int num=12;
int nums = new
int[coins.length][num];
for (int i = 0; i < num; i++)
for (int i = 1; i < coins.length; i++)
else}}
system.out.println(nums[coins.length-1][num-1]);
}
總錢數為6(6不為單個硬幣的面額)的問題最優解,一定是從1,2,3,4,5的子問題的最優解中得出來的。
初始化,當總錢數為單個硬幣的面額時,最小個數一定為1。 建立乙個陣列number, 儲存硬幣個數。
從1開始,當總錢數為1時,因為有面額為1的硬幣,那麼個數為 number[1]=1 。
總錢數為2時: 因為沒有面額為2的硬幣, 那麼number[2] =number[1]+number[1]=2.
當總錢數為3時,因為有面額為3的硬幣,那麼個數為 number[3]=1 。
當總錢數為4時, 因為沒有面額為2的硬幣,那麼number[4]=min 。
...以此類推
當總錢數為11時:number[11]=min
最終,至少需要 3 個硬幣構成 11 元錢number[11]。
**如下:
publicstatic
void
selectsummoneyasvariable() ;
int num=12;
int number = new
int[num];
for (int i = 0; i < coins.length; i++)
for (int i = 2; i < num; i++)
if (number[i] !=1)
}for (int i = 0; i < number.length; i++)
}
動態規劃零錢問題
問題 給你 k 種面值的硬幣,面值分別為 c1,c2 ck,每種硬幣的數量無限,再給乙個總金額 amount,問你最少需要幾枚硬幣湊出這個金額,如果不可能湊出,演算法返回 1 比如說 k 3,面值分別為 2,5,10,總金額 amount 11。那麼最少需要 4枚硬幣湊出,即 11 5 2 2 2。...
動態規劃 零錢問題 python
零錢問題 暴力遞迴 遞推關係 對arr index 的使用的次數情況進行列舉,for int i 0,arr index i aim,i 對於每乙個i都對應乙個列舉的情況,在該列舉情況下可以重新調整引數,此時可以使用的零錢陣列是arr中index 1開始及之後的陣列部分,新的目標值是aim aim ...
動態規劃 零錢兌換
問題描述 給定不同面額的硬幣 coins 和乙個總金額 amount。編寫乙個函式來計算可以湊成總金額所需的最少的硬幣個數。如果沒有任何一種硬幣組合能組成總金額,返回 1。你可以認為每種硬幣的數量是無限的。比如coins 1,2,5 amount 11,11 5 5 1,最終結果為3 演算法思路 本...