Hello,各位亲爱的同学们~
今天带来一道稍稍带点难度的编程题,0/1背包问题。
首先我们先来审题
Question
有n件物品(每种物品都只有一件),w[i]表示物品的重量,c[i]表示物品的价值,现有一个容量为V的背包,应该如何选物品使得书包内装的物品的f[i]之和最大呢?
由题可知,我们需要完成一次动态规划,来选择最优方案。(我用的是一维数组的方法!!)二维数组的同志们可以进行参考!
First
把框架打好
#include <iostream>
using namespace std;
int main(){
return 0;
}
将变量设定好,并将其赋值
int i,j,m,n;
cin >> m >> n;
for(i = 1;i <= n;i++)
cin >> w[i] >> c[i];
Second
我们开始进行动态规划,找出最优值
for(i = 1;i <= n;i++){
for(j = m;j >= 0;j--){//for(j = m;j >= w[i];j--)
if(j >= w[i])
f[j] = max(f[j],f[j-w[i]]+c[i]);
}
Last
最后把最优值打印出来
cout <<f[m];
所以连贯代码如下:
#include <iostream>
using namespace std;
//w,c数组分别存储重量与价值f数组存储对应的总价值
int main(){
//1 m表示背包总容量,n 表示宝石总数
int i,j,m,n;
cin >> m >> n;
//2 循环输入宝石重量与对应的价值
for(i = 1;i <= n;i++)
cin >> w[i] >> c[i];
//3 动态求解每一个小问题:宝石个数为i 背包大小为j
// 设f[j]表示前i块宝石,背包容量为j 时的最优价值
for(i = 1;i <= n;i++){
for(j = m;j >= 0;j--){//for(j = m;j >= w[i];j--)
if(j >= w[i])
f[j] = max(f[j],f[j-w[i]]+c[i]);
}
//输出最终最优解
cout <<f[m];
}
二维数组的方法(可以类比上方一维数组的方法 )
#include <iostream>
using namespace std;
int w[200],c[200],f[200][200];
int main(){
int i,j,m,n;
cin >> m >> n;
for(i = 1;i <= n;i++) cin >> w[i] >> c[i];
for(i = 1;i <= n;i++){
for(j = 1;j <= m;j++){
if(j >= w[i]){
f[i][j] = max(f[i-1][j-w[i]]+c[i],f[i-1][j];
}else{
f[i][j] = f[i-1][j];
}
}
}
cout << f[n][m];
return 0;
}