Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Dynamic Programming Practice: 0-1 Knapsack and Weight Measurement Problems

Tech 1

The 0-1 knapsack problem serves as a foundational dynamic programming challenge. Given a time limit t and m herbs, each with a collection time and value, the goal is to maximize total value without exceeding the time limit. The solution uses a 2D DP table where dp[i][j] represents the maximum value achievable using the first i items within time j. For each item, if its time cost exceeds the current capacity, its skipped; otherwise, the algorithm chooses between including or excluding it based on which yields higher value.

#include <bits/stdc++.h>
using namespace std;

int main() {
    int t, m;
    cin >> t >> m;
    vector<int> time(m + 1), val(m + 1);
    for (int i = 1; i <= m; ++i) {
        cin >> time[i] >> val[i];
    }

    vector<vector<int>> dp(m + 1, vector<int>(t + 1, 0));
    for (int i = 1; i <= m; ++i) {
        for (int j = 1; j <= t; ++j) {
            if (time[i] > j) {
                dp[i][j] = dp[i - 1][j];
            } else {
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - time[i]] + val[i]);
            }
        }
    }

    cout << dp[m][t] << endl;
    return 0;
}

A more complex variant appears in the weight measurement problem: given n weights, determine how many distinct positive masses can be measured by placing weights on either side of a balance. This extends the knapsack idea by allowing both addition and subtraction of weights. The state possible[i][w] indicates whether mass w can be formed using the first i weights. Transitions consider three cases: not using the current weight, adding it to the same side (increasing mass), or placing it on the opposite side (effectively subtracting its value, handled via asbolute difference).

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> w(n + 1);
    int total = 0;
    for (int i = 1; i <= n; ++i) {
        cin >> w[i];
        total += w[i];
    }

    vector<vector<bool>> possible(n + 1, vector<bool>(total + 1, false));
    possible[0][0] = true;

    for (int i = 1; i <= n; ++i) {
        for (int mass = 0; mass <= total; ++mass) {
            // Case 1: skip current weight
            if (possible[i - 1][mass]) {
                possible[i][mass] = true;
            }
            // Case 2: add to same side
            if (mass >= w[i] && possible[i - 1][mass - w[i]]) {
                possible[i][mass] = true;
            }
            // Case 3: place on opposite side (subtract)
            int diff = abs(mass - w[i]);
            if (possible[i - 1][diff]) {
                possible[i][mass] = true;
            }
        }
    }

    int count = 0;
    for (int i = 1; i <= total; ++i) {
        if (possible[n][i]) ++count;
    }
    cout << count << endl;
    return 0;
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.