- 《算法基础》 动态规划-背包问题
- 1. 01背包问题
- 2.完全背包问题
- 3.多重背包问题
- 4.分组背包问题
最核心最简洁的的代码:
1.01背包问题
for (int i = 1; i <=n; i ++)
for (int j = m; j >= v[i]; j --) {
f[j] = max(f[j], f[j - v[i]] + w[i]);
}
2.完全背包问题
for (int i = 1; i <= n; i ++)
for (int j = v[i]; j <= m; j ++)
f[j] = max(f[j], f[j - v[i]] + w[i]);
3.多重背包问题
for (int i = 1; i <= n; i ++)
for (int j = 0; j <= m; j ++)
for (int k = 0; k <= s[i] && k * v[i] <= j; k ++)
f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + w[i] * k);
4.分组背包问题
for (int i = 1; i <= n; i ++)
for (int j = m; j >= 0; j --)
for (int k = 0; k < s[i]; k ++)
if (v[i][k] <= j)
f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
1. 01背包问题
#include2.完全背包问题#include #include using namespace std; const int N = 1010; int v[N], w[N]; int n, m; int f[N][N]; // f[0][0 - m] 自动初始化为0 int main() { cin >> 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 = 0; j <= m; j ++) { f[i][j] = f[i - 1][j]; if (j >= v[i]) { f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]); } } } cout << f[n][m] << endl; return 0; } //一维滚动数组
#include3.多重背包问题#include #include #include using namespace std; typedef long long LL; const int N = 110, mod = 1e9 + 7; unordered_map primes; int main() { int n; cin >> n; while (n --) { int x; cin >> x; for (int i = 2; i <= x / i; i ++) { while (x % i == 0) { x /= i; primes[i] ++; } } if (x > 1) primes[x] ++; } LL res = 1; for (auto prime : primes) { res = res * (prime.second + 1) % mod; } cout << res << endl; return 0; }
#include#include using namespace std; const int N = 110; int n, m; int v[N], w[N], s[N]; int f[N][N]; int main() { cin >> n >> m; for (int i = 1; i <= n; i ++) cin >> v[i] >> w[i] >> s[i]; for (int i = 1; i <= n; i ++) for (int j = 0; j <= m; j ++) for (int k = 0; k <= s[i] && k * v[i] <= j; k ++) f[i][j] = max(f[i][j], f[i - 1][j - k * v[i]] + w[i] * k); cout << f[n][m] << endl; return 0; }
多重背包问题的二进制优化
#include4.分组背包问题#include using namespace std; const int N = 12010, M = 2010; int n, m; int v[N], w[N]; int f[M]; int main() { cin >> n >> m; int cnt = 0; for (int i = 1; i <= n; i ++) { int a, b, s; cin >> a >> b >> s; int k = 1; while (k <=s) { cnt ++; v[cnt] = a * k; w[cnt] = b * k; s = s - k; k = k * 2; } if (s > 0) { cnt ++; v[cnt] = a * s; w[cnt] = b * s; } } n = cnt; for (int i = 1; i <= n; i ++) for (int j = m; j >= v[i]; j --) f[j] = max(f[j], f[j - v[i]] + w[i]); cout << f[m] << endl; return 0; }
#include#include using namespace std; const int N = 110; int n , m; int v[N][N], w[N][N], s[N]; int f[N]; int main() { cin >> n >> m; for (int i = 1; i <= n; i ++) { cin >> s[i]; for (int j = 0; j < s[i]; j ++) { cin >> v[i][j] >> w[i][j]; } } for (int i = 1; i <= n; i ++) for (int j = m; j >= 0; j --) for (int k = 0; k < s[i]; k ++) if (v[i][k] <= j) f[j] = max(f[j], f[j - v[i][k]] + w[i][k]); cout << f[m] << endl; return 0; }



