NeFut Logo NeFut
Admin Login

In-Depth Analysis of Complex Knapsack Problems: State Design and Algorithm Derivation for Grouped and Mixed Knapsacks

Published at: 2026-05-27 09:17 Last updated: 2026-06-10 09:24
#algorithm #Dynamic Programming #DP

Core Logic and Mathematical Principles

The essence of complex knapsack problems (such as grouped knapsack and mixed knapsack) is dimensionality reduction mapping of state space and pruning of decision trees. When faced with complex constraints in examinations, we need to redefine "phases" and "intra-state exclusivity" to force non-linear constraints to be mapped onto the linear knapsack axis.

1. The Exclusive Logic of Grouped Knapsack

The grouped knapsack stipulates that items are divided into several groups, where items within each group are mutually exclusive (i.e., at most one item can be selected from each group).

2. The Polymorphic Fusion of Mixed Knapsack

The mixed knapsack refers to items that can be taken once (0-1), infinitely (complete), or a limited number of times (multiple).


State Design and Algorithm Derivation

Mathematical Derivation and One-Dimensional Dimensionality Reduction of Grouped Knapsack

$$f[j] = \max \bigg( f[j], \max_{(w, v) \text{ in } G_k} \bigg\{ f[j - w] + v \bigg\} \bigg)$$


C++ Standard Source Code (NOIP Style)

The following source code integrates the grouped knapsack and mixed knapsack standard implementations in one program, perfectly compatible with Linux g++ -O2 environment.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int MAXV = 1005;
int f[MAXV];

struct Item {
    int w, v;
};

// Data structure to store grouped knapsack
vector<Item> group[105]; 

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int n, max_v;
    if (!(cin >> n >> max_v)) return 0;

    // ==================== Typical Scenario 1: Mixed Knapsack Processing ====================
    for (int i = 1; i <= n; ++i) {
        int w, v, p; // p indicates quantity: p=-1 for 0-1 knapsack, p=0 for complete knapsack, p>0 for multiple knapsack
        cin >> w >> v >> p;

        if (p == -1) {
            // 0-1 Knapsack: Direct one-dimensional reverse
            for (int j = max_v; j >= w; --j) {
                f[j] = max(f[j], f[j - w] + v);
            }
        } 
        else if (p == 0) {
            // Complete Knapsack: Direct one-dimensional forward
            for (int j = w; j <= max_v; ++j) {
                f[j] = max(f[j], f[j - w] + v);
            }
        } 
        else if (p > 0) {
            // Multiple Knapsack: Direct binary splitting into 0-1 knapsack granules, in-place processing
            for (int k = 1; p >= k; k <<= 1) {
                int cur_w = k * w;
                int cur_v = k * v;
                for (int j = max_v; j >= cur_w; --j) {
                    f[j] = max(f[j], f[j - cur_w] + cur_v);
                }
                p -= k;
            }
            if (p > 0) {
                int cur_w = p * w;
                int cur_v = p * v;
                for (int j = max_v; j >= cur_w; --j) {
                    f[j] = max(f[j], f[j - cur_w] + cur_v);
                }
            }
        }
    }

    // ==================== Typical Scenario 2: Grouped Knapsack Processing ====================
    int m, g_num; // m items, g_num groups
    cin >> m >> g_num;
    for (int i = 1; i <= m; ++i) {
        int w, v, g_id;
        cin >> w >> v >> g_id;
        group[g_id].push_back({w, v});
    }

    for (int k = 1; k <= g_num; ++k) {
        // Critical Pitfall: The capacity loop must be nested between the "group loop" and the "group item loop"
        for (int j = max_v; j >= 0; --j) {
            for (const auto& item : group[k]) {
                if (j >= item.w) {
                    f[j] = max(f[j], f[j - item.w] + item.v);
                }
            }
        }
    }

    cout << f[max_v] << "\n";
    return 0;
}

NOIP Practical Pitfall Guide

1. Mistakenly Writing Item Loop Outside Capacity Loop for Grouped Knapsack

2. Failing to Dynamically Synchronize Capacity Boundaries When Splitting Multiple Knapsack


Classic NOIP/Luogu Real Questions

1. Luogu P1757 The Grouped Knapsack Problem

2. Luogu P1064 [NOIP2006 Advanced Group] Jinming's Budget Plan

  1. Buy only the main item;
  2. Buy the main item + Attachment 1;
  3. Buy the main item + Attachment 2;
  4. Buy the main item + Attachment 1 + Attachment 2. Calculate the total volume and total value of these 4 combinations as 4 parallel items stored in the corresponding group of that main item. Next, directly apply the standard grouped knapsack loop control structure to perfectly reduce the complex tree-like dependency constraints into mutually exclusive choices on linear space.
Original Source: local://14.4

[h] Back to Home