【題解】P1858 多人揹包
阿新 • • 發佈:2020-08-23
P1858 多人揹包
題目描述
求01揹包前k優解的價值和
DD 和好朋友們要去爬山啦!
他們一共有 K 個人,每個人都會背一個包。這些包 的容量是相同的,都是 V。可以裝進揹包裡的一共有 N 種物品,每種物品都有 給定的體積和價值。
在 DD 看來,合理的揹包安排方案是這樣的: 每個人揹包裡裝的物品的總體積恰等於包的容量。 每個包裡的每種物品最多隻有一件,但兩個不同的包中可以存在相同的物品。
任意兩個人,他們包裡的物品清單不能完全相同。 在滿足以上要求的前提下,所有包裡的所有物品的總價值最大是多少呢?
輸入格式
第一行三個數K、V、N
接下來每行兩個數,表示體積和價值
輸出格式
前k優解的價值和
輸入輸出樣例
輸入 #1
2 10 5
3 12
7 20
2 4
5 6
1 1
輸出 #1
57
說明/提示
對於100%的資料,
K≤50,V≤5000,N≤200
題解
很多很多人,意思就是體積一樣但是有很多很多不同的方案
狀態:
$ f[i][j][k] $ 前i個人,體積為j,第k大的價值
決策:第i個物品選不選
歸併轉移
code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorithm> #include <cmath> using namespace std; int k , V , n , ans; int w[210] , v[210]; int now[55]; int f[5010][210] ; int main() { cin >> k >> V >> n; for (int i = 1 ; i <= n ; i++) { cin >> w[i] >> v[i]; } for (int i = 0 ; i <= V ; i++) { for (int j = 1 ; j <= k ; j++) f[i][j] = -10000; } f[0][1] = 0;//體積為零時最優價值為0 //第2優、第3優、··第k優都要負無窮 for (int i = 1 ; i <= n ; i++) { for (int j = V ; j >= w[i] ; j--) { int cnt = 0 , c1 = 1 , c2 = 1; while(cnt <= k) { if(f[j][c1] >= f[j - w[i]][c2] + v[i]) now[++cnt] = f[j][c1++]; else now[++cnt] = f[j - w[i]][c2++] + v[i]; } for (int c = 1 ; c <= k ; c++) { f[j][c] = now[c]; } } } for (int i = 1 ; i <= k ; i++) ans += f[V][i]; cout << ans << endl; return 0; }