#include<bits/stdc++.h>
using namespace std;
#define v first
#define w second
typedef pair<int, int>PII;//利用pair的特性,第一位储存价格,第二位储存价格与重要程度的乘积
const int N = 70, M = 32010;
int n, m;
PII master[N];//储存主件的价格和重要度
vector<PII>servent[N];//储存附件的价格和重要程度,因为不确定附件的数量,所以用vector
int f[M];
int main()
{
cin>>m>>n;
for(int i = 1; i <= n; i ++ ){
int V, p, q;
cin>>V>>p>>q;
if(!q){//如果是主件
master[i] = {V, V * p};
}
else{
servent[q].push_back({V, V * p});//如果是配件,就加入相应的主件组中
}
}
for(int i = 1; i <= n; i ++ ){
if(master[i].v){//如果编号为i的主件存在
for(int j = m; j >= 0; j -- ){//遍历体积
auto &sv = servent[i];
for(int k = 0; k < 1 << sv.size(); k ++ ){//二进制优化,每组的枚举情况
int v = master[i].v, w = master[i].w;
for(int u = 0; u < sv.size(); u ++ ){
if(k >> u & 1){//如果k的二进制右移u位为1,表示这种枚举情况下第u个附件应该被选择
v += sv[u].v;
w += sv[u].w;
}
}
if(j >= v) f[j] = max(f[j], f[j - v] + w);//如果剩余体积允许,再放入
}
}
}
}
cout<<f[m]<<endl;
return 0;
}
AcWing 487 金明的预算方案 题解 (动态规划—DP—背包问题)
最新推荐文章于 2024-07-28 12:57:16 发布