链接:https://nanti.jisuanke.com/t/42381
题意:给定多个物品,每个物品有name,color,power值,然后选取五件名字不同的五件物品,使power总和最大,然后下面还有奖励机制,给定五个名字和一个颜色,如果选择的五个物品某个物品在奖励名字里,其power总和值增加10%,如果颜色值在增加20%
题解:分组背包,把名字相同的分为一组,然后把五件物品当作第一变化量,每个的奖励百分比当作第二变化量

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#include <map>
#include <vector>

using namespace std;

const int maxn = 1e5 + 7;

map<string,int>mp1,mp2;
int dp[maxn][6][16];

struct Node
{
    int val,num;
    string name,color;
    bool operator < (const Node&rhs)const
    {
        return name < rhs.name;
    }
}a[maxn];

vector<Node>G[maxn];

void init(int n)
{
    memset(dp,-1,sizeof(dp));
    mp1.clear();mp2.clear();
    for(int i = 1;i <= n;i++)G[i].clear();
}

int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        int n;scanf("%d",&n);
        init(n);
        for(int i = 1;i <= n;i++)
        {
            cin >> a[i].name >> a[i].color >> a[i].val;
        }

        string tmp;
        for(int i = 1;i <= 5;i++)
        {
            cin >> tmp;mp1[tmp] = 1;
        }
        cin >> tmp;mp2[tmp] = 2;

        sort(a + 1,a + 1 + n);
        int cnt = 0;
        for(int i = 1;i <= n;i++)
        {
            if(a[i].name != a[i - 1].name)
            {
                cnt++;
            }
            a[i].num = mp1[a[i].name] + mp2[a[i].color];
            G[cnt].push_back(a[i]);
        }

        dp[0][0][0] = 0;
        for(int i = 1;i <= cnt;i++)
        {
            for(int k = 0;k <= 5;k++)
            {
                for(int q = 0;q <= 15;q++)
                {
                    dp[i][k][q] = dp[i - 1][k][q];
                }
            }
            for(int j = 0;j < G[i].size();j++)
            {
                int val = G[i][j].val,num = G[i][j].num;

                for(int k = 1;k <= 5;k++)
                {
                    for(int q = num;q <= 15;q++)
                    {
                        if(dp[i - 1][k - 1][q - num] != -1)
                        {
                            dp[i][k][q] = max(dp[i][k][q],dp[i - 1][k - 1][q - num] + val);
                        }
                    }
                }
            }
        }

        int ans = 0;
        for(int i = 0;i <= 5;i++)
        {
            for(int j = 0;j <= 15;j++)
            {
                ans = max(ans,dp[cnt][i][j] * (10 + j) / 10);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}