文章目录
题目描述
思路分析
- 这里明显是使用背包问题,所以这里参考一下背包这个模板题的内容
- 这个是朴素版的模板,没有经过代码的优化
cpp
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1100;
const int V = 1100;
int n,v; // 分别表示背包物体的数量和背包的容量
int f[N][V]; // 这个是状态转移矩阵
int vs[N]; // 不同物体的容量矩阵
int ws1[N]; // 不同物体的价值矩阵
int main(){
cin>>n>>v;
for(int i = 1 ;i <= n;i ++){
cin>>vs[i]>>ws1[i];
}
// 这里需要迭代两次进行计算
for (int i = 1; i <= n; ++i) {
for (int j = 0; j <= v ; ++j) {
f[i][j] = max(f[i -1][j],f[i][j]);
if (j >= vs[i])
f[i][j] = max(f[i][j],f[i - 1][j - vs[i]] + ws1[i]);
}
}
}
- 下述是经过优化之后的模板
- 主要是使用了滚动数组,并且优化了空间之后的操作
cpp
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1100;
const int V = 1100;
int n,v;
int f[N];
int vs[N];
int ws1[N];
int main(){
cin>>n>>v;
for(int i = 1 ;i <= n;i ++){
cin>>vs[i]>>ws1[i];
}
for (int i = 1; i <= n; ++i) {
for (int j = v; j >= 0 && j >= vs[i]; --j) {
f[j] = max(f[j],f[j - vs[i]] + ws1[i]);
}
}
cout<<f[v];
}
背包问题总共有三种,分别是求最大值、最小值和方案数量
实现代码
cpp
// 组合数问题
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
const int M = 11000;
int f[M],g[N];
int main(){
int n, m;
cin>>n>>m;
for(int i = 1;i <= n;i ++) cin>>g[i];
f[0] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = m; j >= 1 && j >= g[i]; --j) {
// f[j] = max(f[j],f[j - g[i]] + g[i]);
f[j] = f[j] + f[j - g[i]];
}
}
cout<<f[m]<<endl;
}
分析总结
- 这里要明白最大值、最小值和装载货物数量之间的关系。
- 同时还要记住这是一个模板题,记住模板就是会做。