基础背包问题

01背包

有N种物品,第i种物品的体积是v[i],价值是w[i],每件物品最多只能选1件。有一个容量为V的背包,问将哪些物品装入背包,可使这些物品的总体积不超过背包,并且总价值最大,输出最大价值。

#include <bits/stdc++.h>
using i64 = long long;

void solve() {
    int N, V;
    std::cin >> N >> V;
    std::vector<int> v(N+1), w(N+1);
    for (int i = 1; i <= N; i++) {
        std::cin >> v[i] >> w[i];
    }
    std::vector<int> dp1(V+1), dp2(V+1);
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= V; j++) {
            dp2[j] = dp1[j];
            if (j >= v[i]) {
                dp2[j] = std::max(dp2[j], w[i]+dp1[j-v[i]]);
            }
        }
        std::swap(dp1, dp2);
    }
    std::cout << dp1[V] << "\n";
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

完全背包

有N种物品,第i种物品的体积是v[i],价值是w[i],每种物品都有无数多件。有一个容量为V的背包,问将哪些物品装入背包,可使这些物品的总体积不超过背包,并且总价值最大,输出最大价值。

#include <bits/stdc++.h>
using i64 = long long;

void solve() {
    int N, V;
    std::cin >> N >> V;
    std::vector<int> v(N+1), w(N+1);
    for (int i = 1; i <= N; i++) {
        std::cin >> v[i] >> w[i];
    }
    std::vector<int> dp1(V+1), dp2(V+1);
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= V; j++) {
            dp2[j] = dp1[j];
            if (j >= v[i]) {
                dp2[j] = std::max(dp2[j], w[i]+dp2[j-v[i]]);
            }
        }
        std::swap(dp1, dp2);
    }
    std::cout << dp1[V] << "\n";
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

多重背包

有N种物品,第i种物品的体积是v[i],价值是w[i],共有s[i]件。有一个容量为V的背包,问将哪些物品装入背包,可使这些物品的总体积不超过背包,并且总价值最大,输出最大价值。

#include <bits/stdc++.h>
using i64 = long long;

void solve() {
    int N, V;
    std::cin >> N >> V;
    std::vector<int> nv{0};
    std::vector<int> nw{0};
    for (int i = 0; i < N; i++) {
        int v, w, s;
        std::cin >> v >> w >> s;
        for (int i = 1; s > i; i *= 2) {
            nv.push_back(i * v);
            nw.push_back(i * w);
            s -= i;
        }
        nv.push_back(s * v);
        nw.push_back(s * w);
    }
    int nn = nv.size() - 1;
    std::vector<int> dp1(V+1), dp2(V+1);
    for (int i = 1; i <= nn; i++) {
        for (int j = 1; j <= V; j++) {
            dp2[j] = dp1[j];
            if (j >= nv[i]) {
                dp2[j] = std::max(dp2[j], nw[i]+dp1[j-nv[i]]);
            }
        }
        std::swap(dp1, dp2);
    }
    std::cout << dp1[V] << "\n";
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}

分组背包

有N组物品,第i组物品有s[i]件,体积为v[i][j],价值为w[i][j],其中i是组号,j是组内编号,同一组内物品最多只能选1件。有容量为V的背包,问将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大,输出最大价值。

#include <bits/stdc++.h>
using i64 = long long;

void solve() {
    int N, V;
    std::cin >> N >> V;
    std::vector<std::vector<int>> v(N+1), w(N+1);
    for (int i = 1; i <= N; i++) {
        int s;
        std::cin >> s;
        v[i].resize(s);
        w[i].resize(s);
        for (int j = 0; j < s; j++) {
            std::cin >> v[i][j] >> w[i][j];
        }
    }
    std::vector<int> dp1(V+1), dp2(V+1);
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= V; j++) {
            dp2[j] = dp1[j];
            for (int k = 0; k < v[i].size(); k++) {
                if (j >= v[i][k]) {
                    dp2[j] = std::max(dp2[j], w[i][k]+dp1[j-v[i][k]]);
                }
            }
        }
        std::swap(dp1, dp2);
    }
    std::cout << dp1[V] << "\n";
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
    int t = 1;
    while (t--) solve();
    return 0;
}
posted @ 2024-06-18 23:01  chenfy27  阅读(7)  评论(0编辑  收藏  举报