多重揹包問題描述:有編號分別為a,b,c的三件物品,它們的重量分別是1,2,2,它們的價值分別是6,10,20,他們的數目分別是10,5,2,現在給你個承重為 8 的揹包,如何讓揹包裡裝入的物品具有最大的價值總和?
多重揹包和01揹包、完全揹包的區別:多重揹包中每個物品的個數都是給定的,可能不是乙個,絕對不是無限個。
有兩種解法,解題思路:
作為乙個新問題考慮,由於每個物品多了數目限制,因此初始化和遞推公式都需要更改一下。初始化時,只考慮一件物品a時,f[1][j] = min。 計算考慮i件物品承重限制為y時最大價值f[i][y]時,遞推公式考慮兩種情況,要麼第 i 件物品一件也不放,就是f[i-1][y], 要麼第 i 件物品放 k 件,其中 1 <= k <= (y/weight[i]),考慮這一共 k+1 種情況取其中的最大價值即為f[i][y]的值,即f[i][y] = max。 這裡為什麼不能像完全揹包一樣直接考慮f[i][y-weight[i]]+value[i]呢?因為這樣不容易判斷第 i 件物品的個數是否超過限制數量 num[i]。
name
weight
value
num012
3456
78c2
20206
2026
4046
525864b
21050
6121824
3036
4248a1
61006
1218
2430
3642
48**如下:
輸入示例:#include using namespace std;
int knapsack_limitnum(int *w, int *v, int *n, int *res, int n, int c)
for(int i = 0; i < n; i++)
for(int j = 0; j < c+1; j++)
f[i][j] = 0;
for(int y = 1; y < c+1; y++)
for(int i = 1; i < n; i++)
else }}
}for(int i = 0; i < n; i++)
value = f[n-1][c];
int j = n-1;
int y = c;
while(j)
}j--;
}res[0] = f[0][y]/v[0];
for(int i = 0;i < n; i++)
delete f;
f = 0;
return value;
}void test1()
int value = knapsack_limitnum(w, v, n, res, n, c);
cout << value << endl;
for(int i = 0; i < n; i++)
cout << res[i] << " ";
cout << endl;
delete res; res = 0;
delete n; n = 0;
delete v; v = 0;
delete w; w = 0;
}}int main()
輸出結果:3 8 //3件物品,揹包承重最大為8
1 6 10 //第一件物品, 重量為1,價值為6, 數目為10
2 10 5
2 20 2
多重揹包的第二種解法,由01揹包的分析可知,01揹包中允許放入的物品有重複,即01揹包中如果考慮要放入的物品的重量和**相同,不影響最終的結果,因為我們可以考慮把多重揹包問題中限制數目的物品拆分成單獨的一件件物品,作為01揹包問題考慮。問題解法和01揹包一致,這裡不再列舉出動態規劃的**了。0 6 12 18 24 30 36 42 48 //放入第一種物品,承重限制為0-8的最優值結果
0 6 12 18 24 30 36 42 48 //放入第一種和第二種物品,承重限制為0-8的最優值結果
0 6 20 26 40 46 52 58 64 //放入三種物品,承重限制為0-8的最優值結果
64 //原問題的解,在揹包承重為8中放3種物品最大價值為64
4 0 2 //最優解對應第一件物品放4個,第二件物品放0個,第三件物品放2個,即4*6+0*10+2*20 = 64
**:
輸入示例:#include #include using namespace std;
int knapsack_limitnum(vector&w, vector&v, vector&res, int c)
for(int i = 0; i < w.size(); i++)
for(int i = 1; i < c+1; i++)
for(int i = 1; i < w.size(); i++)
else }}
value = f[w.size()-1][c];
int j = w.size()-1;
int y = c;
while(j)
j--;
}res[0] = (f[0][y])?1:0;
for(int i = 0; i < w.size(); i++)
delete f;
f = 0;
return value;
}void test1()
i++;
}vectorres;
for(int i = 0;i < w.size(); i++)
res.push_back(0);
int value = knapsack_limitnum(w, v, res, c);
cout << value << endl;
i = 0;
int j = 0;
int count = 0, sum = n[i];
while(j < res.size())
else
j++;
}cout << count << endl;
delete n; n = 0;
}}int main()
執行結果:3 8 //3件物品,揹包承重最大為8
1 6 10 //第一件物品, 重量為1,價值為6, 數目為10
2 10 5
2 20 2
64 //原問題的解,在揹包承重為8中放3種物品最大價值為64
4 0 2 //最優解對應第一件物品放4個,第二件物品放0個,第三件物品放2個,即4*6+0*10+2*20 = 64
多維多重揹包問題 多重揹包問題
悼念512汶川大 遇難同胞 珍惜現在,感恩生活 急!災區的食物依然短缺!為了挽救災區同胞的生命,心繫災區同胞的你準備自己採購一些糧食支援災區,現在假設你一共有資金n元,而市場有m種大公尺,每種大公尺都是袋裝產品,其 不等,並且只能整袋購買。請問 你用有限的資金最多能採購多少公斤糧食呢?後記 人生是乙...
揹包問題 多重揹包
有n種物品和乙個容量為w的揹包。第i種物品最多有n i 件可用,每件重量是w i 價值是v i 求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。1.使用三重迴圈進行遞推 狀態轉移式為 dp i j max 關鍵 如下 void solve printf d n dp n ...
多重揹包問題
有n種物品和乙個容量為v的揹包。第i種物品最多有n i 件可用,每件費用是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。這題目和完全揹包問題很類似。基本的方程只需將完全揹包問題的方程略微一改即可,因為對於第i種物品有n i 1種策略 取0件,取1件...