很久很久以前,有一位國王擁有5座金礦,每座金礦的**儲量不同,需要參與挖掘的工人人數也不同。例如有的金礦儲量是500kg**,需要5個工人來挖掘;有的金礦儲量是200kg**,需要3個工人來挖掘…如果參與挖礦的工人的總數是10。每座金礦要麼全挖,要麼不挖,不能派出一半人挖取一半的金礦。要求用程式求出,要想得到盡可能多的**,應該選擇挖取哪幾座金礦? 《漫畫演算法》動態規劃:對於最後的金礦,都有挖或者不挖的選項:
對比兩種情況的收益,最終可得到最大收益。
①400kg/5人②500kg/5人③200kg/3人④300kg/4人⑤350kg/3人
如何確定挖不挖⑤:比較a.10個人挖前4個的收益和b.7個人挖前4個的收益+⑤的收益
7個人挖4座
依次類推,把問題依次拆分。一直把問題簡化成在0個金礦或0個工人時的最優選擇,這個收益結果顯然是0,也就是問題的邊界 。
設金礦數量為n,工人數為w,金礦開採需要的工人數量為陣列p,金礦儲量為陣列g,獲得的收益為f(n,w) f(n
,w)=
0(n=
0或w=
0)f(n,w) = 0 (n=0或w=0)
f(n,w)
=0(n
=0或w
=0)
f (n
,w)=
f(n−
1,w)
(n≥1
,wn−1]
)f(n,w) = f(n-1,w) (n≥1, wf(
n,w)
=f(n
−1,w
)(n≥1,w
n−1]
) f (n
,w)=
max(
f(n−
1,w)
,f(n
−1,w
−p[n
−1]+
g[n−
1)])
(n>=1
,p>=p
[n−1
])f(n,w)=max(f(n-1, w), f(n-1, w-p[n-1]+g[n-1)]) (n>= 1, p>=p[n-1])
f(n,w)
=max
(f(n
−1,w
),f(
n−1,
w−p[
n−1]
+g[n
−1)]
)(n>=1
,p>=p
[n−1
])
/**
* @param w 工人數量
* @param n 金礦數量
* @param p 金礦開採需要的工人數量
* @param g 金礦儲量
* @return 最優
*/// 時間複雜度o(2^n)
從上圖可發現在遞迴的時候出現了很多次的重複呼叫,為解決此問題我們可選擇乙個二維陣列來記錄中間資料,如下:
使用上面的方程填滿這張表就可以得出最終資料:
* 獲得金礦最優收益
* * @param w 工人數量
* @param p 金礦開採需要的工人數量
* @param g 金礦儲量
* @return 最大收益
*/public
static
intgetbestgoldmining
(int w,
int[
] p,
int[
] g)
else}}
//返回最後1個格仔的值
return resulttable[g.length]
[w];
}
public
static
intgetbestgoldminin**2
(int w,
int[
] p,
int[
] g)}}
//返回最後1個格仔的值
return results[w]
;}
leetcode 黃金礦工
你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的 數量 如果該單元格是空的,那麼就是 0。為了使收益最大化,礦工需要按以下規則來開採 每當礦工進入乙個單元,就會收集該單元格中的所有 礦工每次可以從當...
黃金礦工 回溯演算法
你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的 數量 如果該單元格是空的,那麼就是 0。為了使收益最大化,礦工需要按以下規則來開採 示例 2 輸入 grid 1,0,7 2,0,6 3,4,5 0...
力扣 黃金礦工
你要開發一座金礦,地質勘測學家已經探明了這座金礦中的資源分布,並用大小為 m n 的網格 grid 進行了標註。每個單元格中的整數就表示這一單元格中的 數量 如果該單元格是空的,那麼就是 0。為了使收益最大化,礦工需要按以下規則來開採 每當礦工進入乙個單元,就會收集該單元格中的所有 礦工每次可以從當...