hdu 2602 Bone Collector(01背包)

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602

题意

已知 $N$ 个物品的价值和体积,背包空间为 $V$,求能装进背包的最大价值。

题解一

$dp_{ij}$ 表示把前 $i$ 个物品装入容量为 $j$ 的背包中获得的最大价值。

代码一

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;

int val[N], cost[N];
int dp[N][N];

void solve() {
    int N, V; cin >> N >> V;
    for (int i = 1; i <= N; i++) cin >> val[i];
    for (int i = 1; i <= N; i++) cin >> cost[i];
    memset(dp, 0, sizeof dp);
    for (int i = 1; i <= N; i++)
        for (int j = 0; j <= V; j++)
            if (cost[i] > j)
                dp[i][j] = dp[i - 1][j];
            else
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - cost[i]] + val[i]);
    cout << dp[N][V] << "\n";
}

int main() {
    int T; cin >> T;
    while (T--) solve();
}

题解二

注意到,每层的状态为上一层从小到大的转移,所以每次可以从大到小更新原有层,这样空间复杂度就由原来的 $S_{(n^2)}$ 压缩到了 $S_{(n)}$ 。

代码

#include <bits/stdc++.h>
using namespace std;
const int N = 1010;

int val[N], cost[N];
int dp[N];

void solve() {
    int N, V; cin >> N >> V;
    for (int i = 1; i <= N; i++) cin >> val[i];
    for (int i = 1; i <= N; i++) cin >> cost[i];
    memset(dp, 0, sizeof dp);
    for (int i = 1; i <= N; i++)
        for (int j = V; j >= cost[i]; j--)
            dp[j] = max(dp[j], dp[j - cost[i]] + val[i]);
    cout << dp[V] << "\n";
}

int main() {
    int T; cin >> T;
    while (T--) solve();
}

 

posted @ 2020-06-15 23:30  Kanoon  阅读(135)  评论(0)    收藏  举报