题解 | #购物单#
购物单
https://www.nowcoder.com/practice/f9c6f980eeec43ef85be20755ddbeaf4
#include <iostream>
#include<vector>
using namespace std;
int main() {
int P, n;
cin >> P >> n;
vector<int> price(n);//价格
vector<int> value(n);//重要度
vector<int> temp(n);//p或者q
vector<int> parent;//主件
vector<vector<int>> children(n, vector<int>());//主件的附件集合
for (int i = 0; i < n; i++) {
cin >> price[i] >> value[i] >> temp[i];
if (temp[i] != 0)children[temp[i] - 1].emplace_back(i);
else parent.emplace_back(i);
}
//懒得初始化,使用一维
//dp[i][k]=max(dp[i-1][k],dp[i-1][k-price[i]]+value[i])
vector<int> dp(P + 1, 0);
for (int i = 0; i < parent.size(); i++) {
int index = parent[i];
for (int k = P; k >= price[index]; k -= 10) {
//附件所有可能的取法(包括一件也不取)
for (int m = 0; m < 1 << children[index].size(); m++) {
int weight = price[index];
int val = value[index] * price[index];
//一种情况的一个附件,是否选取
for (int pos = 0; pos < children[index].size(); pos++) {
if (m & (1 << pos)) { //如果第pos位为0则if为假
weight += price[children[index][pos]];
val += value[children[index][pos]] * price[children[index][pos]];
}
}
if (k >= weight) dp[k] = max(dp[k], dp[k - weight] + val);
}
}
}
cout << dp[P] << endl;
return 0;
}
查看6道真题和解析