Question: If someone wants to buy a pair of shoes and has k types of shoes, they must buy at least one pair of shoes to show the cost and value of each pair of shoes, ask the maximum value of the shoes that m yuan can buy.
Idea: grouping and knapsack problems. Unlike a traditional group backpack, each group must have at least one item, and any item in each group can be taken.
Think about the traditional grouping backpack. Choose one or more from each group:
For all group k
for v=V..0
For all I belong to group k
f[v]=max{f[v],f[v-c[i]]+w[i]}
Here, you must select at least one item in each group and perform a backpack on the items in each group. That is, the item is either selected or not selected in this group. To achieve this goal, you only need to swap the second loop with the third one.
Specific solution: Set dp [I] [j] to indicate the maximum value that j yuan can obtain until group I.
dp[i][j] = Max(dp[i][j],dp[i][j-item[i][k].cost]+item[i][k].val, dp[i-1][j-item[i][k].cost]+item[i][k].val)。
Initialize all dp [I] [j] =-1, which indicates that all items are invalid. It is used to ensure that at least one item can be retrieved for each group; dp [0] [0-M] = 0 in order to enable the first group to be legally calculated.
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define LL long # define _ LL _ int64 using namespace std; struct node {int cost, val;} item [12] [110]; int dp [12] [10010]; int num [12]; int n, m, k; void solve () {// note that memset (dp,-1, sizeof (dp); // All Initialization is illegal for (int I = 0; I <= m; I ++) // the initialization of the 0th group is legal, calculate the first group of dp [0] [I] = 0; for (int I = 1; I <= k; I ++) {for (int j = 0; j <num [I]; j ++) {for (int g = m; g> = item [I] [j]. cost; g --) {// pay attention to the order of the two judgment conditions if (dp [ I] [g-item [I] [j]. cost]! =-1) dp [I] [g] = max (dp [I] [g], dp [I] [g-item [I] [j]. cost] + item [I] [j]. val); if (dp [I-1] [g-item [I] [j]. cost]! =-1) dp [I] [g] = max (dp [I] [g], dp [I-1] [g-item [I] [j]. cost] + item [I] [j]. val) ;}}} int main () {while (~ Scanf (% d, & n, & m, & k) {memset (num, 0, sizeof (num); int a, B, c; for (int I = 0; I <n; I ++) {scanf (% d, & a, & B, & c ); item [a] [num [a]. cost = B; item [a] [num [a]. val = c; num [a] ++;} solve (); if (dp [k] [m] <0) printf (Impossible); else printf (% d, dp [k] [m]);} return 0 ;}