现有n件物品,每一件的重量是w[i],价值是v[i]。用一个容量为c的背包来装这些东西, 问如何选择物品才能使装的物品价值最大?(每件物品只能放一次)
输入:
第一行:最大载重量c
第二行:每个集装箱的重量w[i],w[i]小于等于c,用逗号“,”分隔
第三行:每个集装箱对应货物的价值v[i],用逗号“,”分隔
输出:一个整数 表示货运总价值
#include <iostream>
using namespace std;
typedef struct goods {
int weight;
int value;
}goods;
const int Capacity = 11;//总容量
const int N = 5; //物品件数
goods comodity[N + 1] = { {0,0},{1,1},{2,6 }, {5, 18}, {6, 22}, {7, 28} };
int selected[N + 1][Capacity + 1];
int Max(int a,int b) {
return a > b ? a : b;
}
int GetMaxValue() {
for (int w = 0; w <= Capacity; w++)
selected[0][w] = 0; //表示容量为w的背包为空时,其价值为0
for (int i = 1; i <= N; i++)
selected[i][0] = 0; //表示容量为0的背包,其价值为0
for(int i=1;i<=N;i++)
for (int w = 1; w <= Capacity; w++) {
if (comodity[i].weight > w)
selected[i][w] = selected[i - 1][w];//不装第i件物品
else
selected[i][w] = Max(selected[i - 1][w], comodity[i].value + selected[i - 1][w - comodity[i].weight]);//在装与不装之间选个大的
}
return selected[N][Capacity];
}
int main()
{
cout << "Max Value is " << GetMaxValue() << endl;
int remainspace = Capacity;
for (int i = N; i > 0; i--) {
//从最优解出发,将所有满足选中状态的物品编号输出即可得到最优解的组成
if (selected[i][remainspace] == comodity[i].value + selected[i - 1][remainspace - comodity[i].weight]) {
cout << "item " << i << " is selected" << endl;
remainspace -= comodity[i].weight;//空位置大小更新
}
}
return 0;
}
https://www.bilibili.com/video/BV1K4411X766?from=search&seid=5111710240287021888
这个讲的太好了
https://www.cnblogs.com/TWS-YIFEI/p/9761200.html
此时看代码就清楚多了
以上代码在vs上会报错不知道为啥(注释掉的没错)
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int c=5;//容量
int w[505];
int v[505];
int dp[505];
string str1 = "1,2,3", str2 = "6,10,12";
//cin >> c >> str1 >> str2;
int n = str1.size();
int cnt= 0;
for (int i = 0; i < n; ++i){
int num = 0;
while (str1[i] != ','&& i < n){
num = 10 * num + str1[i++] - '0';
}w[cnt++] = num;
}//w数组填入
n = str2.size();
cnt = 0;
for (int i = 0; i < n; ++i){
int num = 0;
while (str2[i] != ','&& i < n){
num = 10 * num + str2[i++] - '0';
}v[cnt++] = num;
}//v数组填入
for (int i = 0; i < cnt; ++i){
int weight = w[i];
for (int j = c; j >= weight; --j){
dp[j] = max(dp[j],dp[j-weight]+v[i]);
}
}
cout << dp[c] << endl;
system("pause");
return 0;
}
//int main() {
// vector<int> weight = { 1, 2, 3 };
// vector<int> value = { 6, 10, 12 };
// int c = 5;
//
// // 初始化
// vector<int> dp(c + 1, 0);
// for (int i = 0; i < weight.size(); i++) { // 遍历物品
// for (int j = c; j >= weight[i]; j--) { // 遍历背包容量
// dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
// }
// }
// cout << dp[c] << endl;
// system("pause");
// return 0;
//}
还有另一种输入方法:
在网页在线上可以ac
https://www.nowcoder.com/questionTerminal/708f0442863a46279cce582c4f508658?questionTypes=000100&page=1&onlyReference=false
#include<iostream>
#include<math.h>
using namespace std;
int main(){
int n,c;
cin>>c>>n;
int w[n],v[n],dp[c+1];
for(int i=0;i<n;i++)
cin>>w[i]>>v[i];
for(int j=0;j<=c;j++)
if(w[0]<=j) dp[j]=v[0];
else dp[j]=0;
for(int i=1;i<n;i++)
for(int j=c;j>=w[i];j--){
dp[j]=max(dp[j], v[i]+dp[j-w[i]]);
}
cout<<dp[c]<<endl;
return 0;
}
感觉一维数组的算法还是有点难懂
这一步在vivo里就没有 但是在牛客上就得有
还是好好记一下二维数组的写法吧
不过下面这个写的也不错
#include <bits/stdc++.h>
using namespace std;
int main()
{
int w, n;//容量 件数
cin>>w>>n;
vector <int> weight(1), value(1);//这个1必须有
for (int i = 0; i < n; i++)
{
int wei, val;
cin >> wei >> val;
weight.push_back(wei);
value.push_back(val);
}
vector<int> result(w + 1);//这个w+1必须有
for (int i = 1; i <= n; i++)
{
for (int j = w; j >=weight[i]; j--)
{
result[j] = max(result[j], result[j - weight[i]] + value[i]);
}
}
cout << result[w] << endl;
return 0;
}
几个for
的条件很重要 麻了
这样改过以后舒服多了 还是用的vector 数组不知道为什么不行
#include <bits/stdc++.h>
using namespace std;
int main()
{
int w, n;//容量 件数
//for (int i = 0; i<n; i++)
//cin >> w[i] >> v[i];
cin>>w>>n;
vector <int> weight, value;//这里去掉了(1)
for (int i = 0; i < n; i++)
{
int wei, val;
cin >> wei >> val;
weight.push_back(wei);
value.push_back(val);
}
vector<int> result(w+1);//这个还是必须要有 因为后面有weight[i]
//但是如果变成一个具体的数字就又会报错 不懂
for (int i = 0; i < n; i++)//因为weight和value数组的第一个元素不是0了
// 所以这里就从0开始 而不是1
{
for (int j = w; j >=weight[i]; j--)
{
result[j] = max(result[j], result[j - weight[i]] + value[i]);
}
}
cout << result[w] << endl;
return 0;
}