我们可以将多重背包分解为0-1背包和完全背包,当物品的(价格*数量)超过总金额时就可以看做是完全背包问题反之就可以看做是0-1背包问题。在转化成0-1背包时有个地方需要注意,我们可以把第i中物品的数量c[i]分成若干数量的集合比如物品i的数量有7种,就可以化为{1,2,4}可以用这集合里面三个元素组合成1~7中任意一种数量,分解的方法为:1,2,4,…….,c[i]-2^k+1
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
const int maxn = 110;
int n, m;
int dp[maxn], p[maxn], h[maxn], c[maxn];
void CompleteBack(int v, int w)
{
for (int i=v; i <= n; i++)
{
dp[i] = max(dp[i], dp[i - v] + w);
}
}
void OnePack(int v, int w)
{
for (int i = n; i >= v; i--)
{
dp[i] = max(dp[i], dp[i - v] + w);
}
}
int main()
{
int C, k = 1, count = 0;
cin >> C;
while (C--)
{
cin >> n >> m;
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= m; i++)
{
cin >> p[i] >> h[i] >> c[i];
if (p[i] * c[i] >= n)
CompleteBack(p[i], h[i]);
else
{
for (int j = 1; j <=c[i]; (j<< 1))
{
OnePack(j*p[i], j*h[i]);
c[i] = c[i] - j;
}
OnePack(p[i] * c[i], h[i] * c[i]);
}
}
cout << dp[n] << endl;
}
}