参考:
【多重背包问题】介绍与核心思想--(朴素方法)_哔哩哔哩_bilibili
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1050;
const int MAXV = 1050;
int v[MAXN]; //拓展后的重量
int w[MAXN]; //拓展后的价值
int s[MAXN]; //存物品的件数
int temp_v[MAXN]; //物品的实际重量
int temp_w[MAXN]; //物品的实际价值
int dp[MAXV];
int n,m;
void knapsak() //当做01背包去做,用滚动数组
{
for(int i=1;i<=n;i++)
for (int j = m; j >= v[i]; j--)
{
dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> temp_v[i];
for (int i = 1; i <= n; i++) cin >> temp_w[i];
int k = 1; //作为拓展的下标
for (int i = 1; i <= n; i++)
{
cin >> s[i]; //读取该物品件数
for (int j = 1; j <= s[i]; j <<= 1) //用二进制法优化,每次让j*2;只要剩下的件数大于j,就循环
{
v[k] = j * temp_v[i]; //当做一个整体去存重量
w[k] = j * temp_w[i];
s[j] -= j; //剩下的件数
k++; //下标+1
}
if (s[i] != 0) //只要剩下的件数不是0,把剩下的放在最后一个数组元素里
{
v[k] = s[i] * temp_v[i];
w[k] = s[i] * temp_w[i];
}
}
n = k; //把物品改成拓展后的,当做01背包去做
knapsak();
cout << dp[m] << endl;
return 0;
}