揹包九講(7)
阿新 • • 發佈:2022-04-21
揹包九講(7)
有依賴的揹包問題
有 N 個物品和一個容量是 V的揹包。
物品之間具有依賴關係,且依賴關係組成一棵樹的形狀。如果選擇一個物品,則必須選擇它的父節點。
如下圖所示:
如果選擇物品5,則必須選擇物品1和2。這是因為2是5的父節點,1是2的父節點。
每件物品的編號是 ii,體積是 vi,價值是 wi,依賴的父節點編號是 pi。物品的下標範圍是 1…N。
求解將哪些物品裝入揹包,可使物品總體積不超過揹包容量,且總價值最大。
輸出最大價值。
輸入格式
第一行有兩個整數 N,V,用空格隔開,分別表示物品個數和揹包容量。
接下來有 N 行資料,每行資料表示一個物品。
第 ii 行有三個整數 vi,wi,pi,用空格隔開,分別表示物品的體積、價值和依賴的物品編號。
如果 pi=−1,表示根節點。 資料保證所有物品構成一棵樹。
輸出格式
輸出一個整數,表示最大價值。
資料範圍
1≤N,V≤100
1≤vi,wi≤100
父節點編號範圍:
- 內部結點:1≤pi≤N
- 根節點 pi=−1
輸入樣例
5 7
2 3 -1
2 2 1
3 5 1
4 7 2
3 6 2
輸出樣例:
11
沒看懂,暫時放上別人的解答,以後再考慮
AcWing 10. 有依賴的揹包問題(思路不同於dxc,但是個人感覺更好理解) - AcWing
#include<iostream> #include<vector> using namespace std; int f[110][110];//f[x][v]表達選擇以x為子樹的物品,在容量不超過v時所獲得的最大價值 vector<int> g[110]; int v[110],w[110]; int n,m,root; int dfs(int x) { for(int i=v[x];i<=m;i++) f[x][i]=w[x];//點x必須選,所以初始化f[x][v[x] ~ m]= w[x] for(int i=0;i<g[x].size();i++) { int y=g[x][i]; dfs(y); for(int j=m;j>=v[x];j--)//j的範圍為v[x]~m, 小於v[x]無法選擇以x為子樹的物品 { for(int k=0;k<=j-v[x];k++)//分給子樹y的空間不能大於j-v[x],不然都無法選根物品x { f[x][j]=max(f[x][j],f[x][j-k]+f[y][k]); } } } } int main() { cin>>n>>m; for(int i=1;i<=n;i++) { int fa; cin>>v[i]>>w[i]>>fa; if(fa==-1) root=i; else g[fa].push_back(i); } dfs(root); cout<<f[root][m]; return 0; }