思路:把次件转换为主件。

举个例子,输入如下

100 5
80 2 0
40 5 1 ==>对应选择该次件和其主件的情况,可以转换为 40+80 2+5 0
20 5 1 ==>对应选择该次件和其主件的情况,可以转换为 20+80 2+5 0
(140 9 0)  ==>新添加的主件,对应两个次件都选的情况,可以转换为 20+40+80 2+2+5 0 
40 3 0
50 2 0

可以看出,次件的组合加上对应主件就相当于一个新的主件。

所以我们需要对输入进行处理,把次件转换成主件。

而对于主件,就可以用01背包的方法去做了。

这个方法应该可以处理任意n个次件的情况。

这里给出可以通过但没有优化的代码。

#include <iostream>
#include <vector>
#include <list>
using namespace std;

// dp[i][j] :=前i件物品,预算不大于j时,最大满意度

struct node{
    int price;
    int importance;
    int parent_node;
    vector<int> child_nodes;
    list<pair<int,int>> partial_sum_price_and_manyidu;
};


int main() {
    int max_price,N;
    cin >> max_price>> N;
    max_price/=10;//减小内存使用
    vector<node> stuffs(N+1);
    list<int> parent_stuff;

    for(int i=1;i<N+1;i++) {
        cin >> stuffs[i].price
        >> stuffs[i].importance
        >> stuffs[i].parent_node;
        stuffs[i].price/=10;
        if(stuffs[i].parent_node==0) {
             parent_stuff.push_back(i);
        }
        else{
            stuffs[stuffs[i].parent_node].child_nodes.push_back(i);
        }
    }

    // 计算选择主件后,所有可能的次件的价格和满意度的组合
    // 相当于把这些次件转换为主件
    // 题目说最多两个次件,就暴力写组合了
        for(auto& node:parent_stuff){
                list<pair<int,int>>& psum= stuffs[node].partial_sum_price_and_manyidu;
                int psum1=stuffs[node].price, psum2= stuffs[node].price*stuffs[node].importance;
                psum.emplace_back(psum1, psum2);
                for(auto& it : stuffs[node].child_nodes){

                        // 大小为一的组合 即主件分别加上每个单独的次件
                        psum1+=stuffs[it].price;
                        psum2+=stuffs[it].price * stuffs[it].importance;
                        psum.emplace_back(psum1,psum2);
                        psum1-=stuffs[it].price;
                        psum2-=stuffs[it].price * stuffs[it].importance;
                }
                if(stuffs[node].child_nodes.size()>1){
                        int& it = stuffs[node].child_nodes[0];
                        int& it1 = stuffs[node].child_nodes[1];
                        psum1+=stuffs[it].price+stuffs[it1].price;
                        psum2+=stuffs[it].price * stuffs[it].importance+stuffs[it1].price * stuffs[it1].importance;
                        psum.emplace_back(psum1,psum2);
                }
        }
    vector<vector<int>> dp(parent_stuff.size()+1,vector<int>(1+max_price));
    int i=1;
    for(auto it : parent_stuff) {
        for(int j=0;j<=max_price;j++) {
                dp[i][j] = dp[i-1][j];//如果j<value,取dp[i-1][j];
            for(const auto& [value,manyidu] : stuffs[it].partial_sum_price_and_manyidu) {
                if(j>=value){ 
                // 这里没有保证部分和的满意度单调,会导致dp[i][j]取最后一个满足该条件的最大值,需要取max
                    dp[i][j] = max(dp[i][j],dp[i-1][j-value]+ manyidu);
                }
            }
        }
        i++;
    }
    cout << 10*dp.back().back();//前面除以10,记得还原。
}
// 64 位输出请用 printf("%lld")