1 基础知识
暂无。。。
2 模板
暂无。。。
3 工程化
题目1:二维费用的背包问题。
解题思路:套用二维费用的背包问题模型即可。
C++代码如下,
#include <iostream>
using namespace std;
const int V1_MAX = 110, V2_MAX = 110;
int n, V1, V2;
int f[V1_MAX][V2_MAX];
int main() {
cin >> n >> V1 >> V2;
for (int i = 1; i <= n; ++i) {
int v1, v2, w;
cin >> v1 >> v2 >> w;
for (int j = V1; j >= v1; --j) {
for (int k = V2; k >= v2; --k) {
f[j][k] = max(f[j][k], f[j-v1][k-v2] + w);
}
}
}
cout << f[V1][V2] << endl;
return 0;
}
题目2:数字组合。
解题思路:DP即可。
状态定义f[i][j]
:从前i个物品中选择,且体积恰好等于j的方案数。
状态转移,以下情况的累加和,
- 不选择第i个物品,即
f[i-1][j]
。 - 选择第i个物品,即
f[i-1]][j - v[i]]
。
初始化f[0][0] = 1
,表示从前0个物品中选择,体积是0的方案数。
最终答案返回f[m]
。
C++代码如下,
#include <iostream>
using namespace std;
const int N = 110, M = 10010;
int n, m;
int v[N];
int f[N][M];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> v[i];
}
f[0][0] = 1;
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] += f[i-1][j-v[i]];
}
}
cout << f[n][m] << endl;
return 0;
}
同样地,可以将状态优化到一维,
#include <iostream>
using namespace std;
const int M = 10010;
int n, m;
int f[M];
int main() {
cin >> n >> m;
f[0] = 1;
for (int i = 0; i < n; ++i) {
int v;
cin >> v;
for (int j = m; j >= v; --j) {
f[j] += f[j-v];
}
}
cout << f[m] << endl;
return 0;
}
题目3:庆功宴。
解题思路:多重背包模型。
C++代码如下,
#include <iostream>
using namespace std;
const int N = 510, M = 6010;
int n, m;
int v[N], w[N], s[N];
int f[N][M];
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]] + k * w[i]);
}
}
}
cout << f[n][m] << endl;
return 0;
}
同样地,可以将状态优化到一维,
#include <iostream>
using namespace std;
const int M = 6010;
int n, m;
int f[M];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
int v, w, s;
cin >> v >> w >> s;
for (int j = m; j >= 0; --j) {
for (int k = 0; k <= s && k * v <= j; ++k) {
f[j] = max(f[j], f[j - k * v] + k * w);
}
}
}
cout << f[m] << endl;
return 0;
}
题目4:买书。
解题思路:完全背包模型求方案数。
C++代码如下,
#include <iostream>
using namespace std;
const int M = 1010;
int m;
int v[5] = {-1, 10, 20, 50, 100};
int f[5][M];
int main() {
cin >> m;
f[0][0] = 1;
for (int i = 1; i <= 4; ++i) {
for (int j = 0; j <= m; ++j) {
f[i][j] += f[i-1][j];
if (j >= v[i]) f[i][j] += f[i][j-v[i]];
}
}
cout << f[4][m] << endl;
return 0;
}
可以将状态优化到一维,
#include <iostream>
using namespace std;
const int M = 1010;
int m;
int v[5] = {-1, 10, 20, 50, 100};
int f[M];
int main() {
cin >> m;
f[0] = 1;
for (int i = 1; i <= 4; ++i) {
for (int j = v[i]; j <= m; ++j) {
f[j] += f[j - v[i]];
}
}
cout << f[m] << endl;
return 0;
}