算法实践9-2 背包

问题:

共有\(n\)种物品可放入背包,物品\(j\)的重量和价值分别为\(w_j\), \(v_j\)。若背包的限重为\(b\),求最大价值。

解析

\(dp[i][j]\)\(j\)容量装前\(i\)个物品能获得的最大值。对于第\(i\)个物品来说,可以选择放入和不放入,那么我们枚举\(j\),就能得到转移方程。

\(dp[i][j] = max(dp[i - 1][j], dp[i][j - v[j]] + w[j])\)

设计

for (int i = 1; i <= n; ++i) {
    for (int j = m; j >= 0; --j) {
        dp[i][j] = dp[i - 1][j];
        if (j < v[i]) continue;
        dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);
        printf("%d %d %d\n", i, j, dp[i][j]);
    }
}

分析

时间复杂度\(O(nm)\)

源码

https://github.com/Sstee1XD/Algorithm_homework/tree/main/实验9-2 01背包

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

const int inf = 0x3f3f3f3f;
const int N = 1e3 + 7;

int dp[N][N];
int v[N], w[N];
int n, m;

void solve() {
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%d %d", &v[i], &w[i]);
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = m; j >= 0; --j) {
            dp[i][j] = dp[i - 1][j];
            if (j < v[i]) continue;
            dp[i][j] = max(dp[i][j], dp[i - 1][j - v[i]] + w[i]);
            printf("%d %d %d\n", i, j, dp[i][j]);
        }
    }
    int ans = 0;
    for (int j = 1; j <= m; ++j) {
        ans = max(ans, dp[n][j]);
    }
    printf("%d\n", ans);
}

int main() {
    // scanf("%d", &t);
    int t = 1;
    while (t--) solve();
    return 0;
}
/*
6 30
4 605
9 672
14 741
19 812
24 885
30 960
*/
posted @ 2021-06-22 23:42  stff577  阅读(50)  评论(0)    收藏  举报