二维数组(完全背包加个限制条件)
#include <iostream>
#include <algorithm>
using namespace std;
int N, V;
int w[111], v[111], s[111], dp[111][111];
int main()
{
cin >> N >> V; //物品容量&总容量
for (int i = 1; i <= N; i++)
cin >> v[i] >> w[i] >> s[i];
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= V; j++)
{
for (int k = 0; k * v[i] <= j && k <= s[i]; k++)
dp[i][j] = max(dp[i][j], dp[i - 1][j - k * v[i]] + k * w[i]);
// cout << dp[i][j] << " ";
}
// cout << endl;
}
cout << dp[N][V];
system("pause");
}
一维数组优化
#include <iostream>
#include <algorithm>
using namespace std;
int N, V;
int w[1111], v[2222], s[2222], dp[2222];
int main()
{
cin >> N >> V; // 物品容量&总容量
for (int i = 1; i <= N; i++)
cin >> v[i] >> w[i] >> s[i]; // 体积&价值
for (int i = 1; i <= N; i++) // 从1号物体开始计算,逐渐增加可选物品
{
for (int j = V; j >= v[i]; j--) // 从最大容量开始计算,逐渐减少至v[i] 反向遍历避免覆盖小索引值出错 j<v[i] => 临时容量小于物体体积
{
for (int k = 1; k * v[i] <= j && k <= s[i]; k++) // 类01背包,这里使用枚举
{
dp[j] = max(dp[j], dp[j - k * v[i]] + k * w[i]); // i号物品的价值加上剩余的背包空间的最大价值
}
// cout << dp[i] << " ";
}
// cout << endl;
}
cout << dp[V];
system("pause");
}
二进制优化(下道题会用)
#include <iostream>
#include <algorithm>
using namespace std;
int N, V, cnt = 1;
int w[1111], v[2222], s[2222], dp[2222];
int new_w[22222], new_v[22222]; // 价值&体积
int main()
{
cin >> N >> V;
for (int i = 1; i <= N; i++)
cin >> v[i] >> w[i] >> s[i];
for (int i = 1; i <= N; i++)
{
for (int j = 1; j < s[i]; j <<= 1) //二进制拆分
{
new_v[cnt] = j * v[i]; // 存体积
new_w[cnt] = j * w[i]; // 存价值
s[i] -= j; // 因为总共会有s[i]件i号物品,这里用二进制合并,枚举出所有情况。
// cout << new_v[cnt] << " " << new_w[cnt] << endl;
cnt++; // 这个和前面合并,vscode调试就看不见新数组的内容了
}
if (s[i]) // 当s[i]>0;
{
new_v[cnt] = s[i] * v[i]; // 存体积
new_w[cnt] = s[i] * w[i]; // 存价值
// cout << new_v[cnt] << " " << new_w[cnt] << endl;
cnt++;
}
}
for (int i = 1; i <= cnt; i++) //01背包
{
for (int j = V; j >= new_v[i]; j--)
{
dp[j] = max(dp[j], dp[j - new_v[i]] + new_w[i]);
// cout << dp[j] << " ";
}
// cout << endl;
}
cout << dp[V];
system("pause");
return 0;
}