ZZU数据结构与算法实验_5
01背包的实现
1.动态规划
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define endl '\n'
#define VI vector<int>
#define pii pair<int, int>
#define rep(i, j, k) for (int i = j; i <= k; ++i)
#define per(i, j, k) for (int i = j; i >= k; --i)
#define print(a) cout << a << endl;
const int inf = 0x3f3f3f3f;
const long long llinf = (long long)0x3f3f3f3f3f3f3f3f;
const long long MOD = (long long)1e9 + 7LL;
const size_t N = (size_t)1e6 + 5;
#define IO \
ios::sync_with_stdio(false); \
std::cin.tie(0); \
std::cout.tie(0)
#define debug(a) std::cerr << "\033[34m" << #a << ':' << a << "\033[0m" << endl
#define debugList(list) \
std::cerr << "\033[34m" << #list << ": ["; \
for (auto& e : list) { \
std::cerr << e << ", "; \
} \
std::cerr << "\b\b]\033[0m" << endl
int m, n;
int v[110], w[110], dp[110][4100];
int ans[110];
void find() {
for (int i = n; i > 1; i--) {
if(dp[i][m] != dp[i-1][m]) {
ans[i] = 1;
m-=w[i];
}
}
ans[1] = (dp[1][m] > 0) ? 1 : 0;
}
void solve() {
cin >> m >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i];
}
for (int i = 1; i <= n; i++) {
cin >> v[i];
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (j >= w[i]) dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
else dp[i][j] = dp[i - 1][j];
}
}
cout << dp[n][m] << endl;
find();
for (int i = 1; i <= n; i++) {
cout << ans[i] << " ";
}
}
signed main() {
IO;
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
solve();
return 0;
}
2.记忆化搜索(备忘录法)
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define endl '\n'
#define VI vector<int>
#define pii pair<int, int>
#define rep(i, j, k) for (int i = j; i <= k; ++i)
#define per(i, j, k) for (int i = j; i >= k; --i)
#define print(a) cout << a << endl;
const int inf = 0x3f3f3f3f;
const long long llinf = (long long)0x3f3f3f3f3f3f3f3f;
const long long MOD = (long long)1e9 + 7LL;
const size_t N = (size_t)1e6 + 5;
#define IO \
ios::sync_with_stdio(false); \
std::cin.tie(0); \
std::cout.tie(0)
#define debug(a) std::cerr << "\033[34m" << #a << ':' << a << "\033[0m" << endl
#define debugList(list) \
std::cerr << "\033[34m" << #list << ": ["; \
for (auto& e : list) { \
std::cerr << e << ", "; \
} \
std::cerr << "\b\b]\033[0m" << endl
int m, n;
int v[110], w[110], dp[110][4100], g[110][4100];
int ans[110];
int dfs(int pos, int nowv) {
if (dp[pos][nowv] != -1) return dp[pos][nowv];
if (pos == n + 1) return dp[pos][nowv] = 0;
int dfs1, dfs2 = -inf;
dfs1 = dfs(pos + 1, nowv);
if (nowv >= w[pos]) dfs2 = dfs(pos + 1, nowv - w[pos]) + v[pos];
if (dfs1 > dfs2) {
dp[pos][nowv] = dfs1;
g[pos][nowv] = nowv;
}
else {
dp[pos][nowv] = dfs2;
g[pos][nowv]= nowv - w[pos];
}
return dp[pos][nowv];
}
void solve() {
memset(dp, -1, sizeof(dp));
cin >> m >> n;
for (int i = 1; i <= n; i++) {
cin >> w[i];
}
for (int i = 1; i <= n; i++) {
cin >> v[i];
}
cout << dfs(1, m) << endl;
for (int i = 1, j = m; i <= n; i++) {
if (g[i][j] != j) {
ans[i] = 1;
j = g[i][j];
}
}
for (int i = 1; i <= n; i++) {
cout << ans[i] << " ";
}
}
signed main() {
IO;
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
solve();
return 0;
}