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(); }

浙公网安备 33010602011771号