【洛谷】依賴揹包 P1064 金明的預算方案
阿新 • • 發佈:2020-12-02
題目大意
給出 m 件物品,每件物品有三個屬性:\(a,b,c\),分別表示該物品的價格,重要度,以及是主件還是附件,如果是附件給出的是主件是哪個。
現在有限制:如果要取附件,一定要取主件,並且同一個主件附件最多取兩個。
定義每個物品的價值為 價格*重要度,現在有 n 元錢,問可以買的最大價值是多少。
思路
把附件和主件捆綁在一起,形成新的物品。
把每個主件可以形成的物品放到同一個組中,做分組揹包即可。
程式碼
#include<bits/stdc++.h> using namespace std; #define pb push_back typedef long long ll; typedef unsigned long long ull; const int inf=0x3f3f3f3f; const int mod=1e9+7; const int seed=233; const int N=4e4+10; int w[100],v[100],dp[N]; vector<int>vec[100]; vector<pair<int,int>>thi[N]; int main() { int n,m; scanf("%d%d",&n,&m); int cnt=0; for(int i=1;i<=m;i++){ int fa; scanf("%d%d%d",&w[i],&v[i],&fa); v[i]*=w[i]; vec[fa].push_back(i); if(!fa) thi[i].pb(make_pair(w[i],v[i])); } for(int i=1;i<=m;i++){ if(!vec[i].size()) continue; for(int j=0;j<vec[i].size();j++){ thi[i].pb(make_pair(w[vec[i][j]]+w[i],v[vec[i][j]]+v[i])); for(int k=j+1;k<vec[i].size();k++) thi[i].pb(make_pair(w[vec[i][j]]+w[vec[i][k]]+w[i],v[vec[i][j]]+v[vec[i][k]]+v[i])); } } for(int i=1;i<=m;i++){ if(!thi[i].size()) continue; for(int j=n;j>=0;j--){ for(int k=0;k<thi[i].size();k++){ if(j>=thi[i][k].first) dp[j]=max(dp[j],dp[j-thi[i][k].first]+thi[i][k].second); } } } printf("%d\n",dp[n]); return 0; }