在8月18號參加了華為的優招機試,三道程式設計題,前兩道難度不算很大,第一題很簡單,第二題是經典的01揹包問題,小偷偷東西,順著這個機會也總結一下這個01揹包問題,對於題目的描述一開始是憑記憶寫的,後來在牛客網上看到了這個面試的題目,應該是對的,不過有小的區別也不影響題目的分析和程式設計實現。
這題目是乙個典型的貪心演算法的題目,最基礎的演算法有幾種
⑴貪心策略:選取價值最大者。
⑵貪心策略:選取重量最小。它的反例與第一種策略的反例差不多。
⑶貪心策略:選取單位重量價值最大的物品。
⑶貪心策略的改進:對於單位重量價值一樣的,則優先選擇重量小的!(相對最優
)
但是這些情況都可以舉出不符合條件的反例。
下面將結合動態規劃提出一種最好的解決辦法,也很最常見的解決辦法,區域性最優。
題目描述
小偷來到了乙個神秘的王宮,突然眼前一亮,發現5個寶貝,每個寶貝的價值都不一樣,且重量也不一樣,但是小偷的揹包攜帶重量有限,所以他不得不在寶貝中做出選擇,才能使偷到的財富最大,請你幫助小偷計算一下。
輸入描述:
寶貝價值:6,3,5,4,6
寶貝重量:2,2,6,5,4
小偷揹包容量:10
輸出描述:
偷到寶貝的總價值:15
示例1
輸入
6,3,5,4,6
2,2,6,5,4
輸出
#include
#include
#include
using namespace std;
intmain()
//初始化第一列為0
for(
int i =
0;i<=
5;i++
)//初始化第一行為0
for(
int j =
0;j<=m;j++
)//執行動態規劃,自小到大計算,生成,value表
for(
int i =
1;i<=
5;i++
)else}}
cout<[m]
}
基本思路是將該問題轉化為子問題進行求解。考慮n件物品在限重m的揹包下可選擇的最大價值f[n][m],這個問題可以分解成兩種情況來考慮:這是乙個非黑即白的問題,因為乙個物品只存在兩種狀態,放入揹包
和沒有放入揹包
.
n1不放入揹包,則問題轉化為f[n-1][m]
,n1不放入揹包,則物品數減一
n1放入揹包,問題轉化為value[n1]+f[n-1][m-weight[n1]]
,n1放入揹包,則揹包承重減少。
原問題的解取上面兩種情況中的最大值。既f[n][m] = max
。接下來問題又變成了求解f[n-1][m]和 f[n-1][m-weight[n1]兩個子問題。然後一直類推到乙個物品時。以此類推的話我們解決原始問題需要子問題的解。我們需要先計算子問題,自底向上求解。解決順序如下表。從左到右,從上到下計算。貨品的順序不影響最後的計算結果。
此**是按照計算的方向來寫的。計算的方法是一樣的,分析方法也是一樣,在此題中沒有要求按序輸出選中的物品,故輸入順序並沒有影響。
第一行和第一列初始化為0,則可以直接代入公式計算。
第二行為只放入第一件物品,揹包的最優值
第三行為只放入前兩件物品,揹包的最優值
…依次類推,最後的f[6][11]即為最優值。
貨品weight
value01
2345
6789
10000
0000
0000
0001
2600
6666
6666
6223
0066
9999
9993
6500
6699
991111144
5400
6699
9101013145
4600
6699
1212
1515
15還有乙個動態規劃的詳細解讀部落格動態規劃扔雞蛋!
01揹包問題 dp
這道題需要從定義去理解 dp i 1 j 定義為 在前i個物品裡面選出來的總體積不大於j的最大的價值 所以這樣就可以知道了,dp i 1 j 就表示在前i個物體裡面選出來的不超過給定體積的最大價值了 所以清楚定義後就有 如果當前超過了當前體積了 那麼他肯定就是dp i 1 j dp i j 了 如果...
01揹包問題(dp)
思路 填表。以下有幾種情況 情況一 第j件放不進去 當前容量i小於第i件物品 這時所得價值為 dp i j dp i j 1 情況二 第j件不放進去 容量足夠 這時所得價值為 dp i j dp i j 1 情況三 第j件放進去 容量足夠 這時所得價值為 dp i weigh j j 1 value...
01揹包問題 DP
有 n件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。第一行兩個整數,n,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,每行兩個整數 vi,wi,用...