本题是多重背包问题,状态转移方程也很容易列出来,但由于本题的数据过大,物品的数量过多,因此我们需要进行二进制优化
首先我们要知道二进制优化的原理
以19为例,如果我们拆分成1,2,4,8,3
我们就可以用之前的五个数表示出1~19的所有数
那么五个数是怎么来的呢
其实就是相加小于等于该数的2的幂次方(1,2,4,8)和那个数与和的差值(3)
学会了二进制优化后,本题就比较简单了,下面附上代码
#include <iostream>
using namespace std;
const int N = 4e4 + 5;
int a[N], b[N], x,y,z,f[N], n, w,k;
int main()
{
cin >> n >> w;
for (int i = 1; i <= n; i++)
{
cin >> x >> y >> z;
for (int j = 1; j <= z; j *= 2)//二进制优化
{
k++;
a[k] = j * x, b[k] = j * y;
z -= j;
}
if (z != 0)
{
k++;
a[k] = z * x, b[k] = z * y;
}
}
for(int i=1;i<=k;i++)//滚动数组
for (int j = w; j >= b[i]; j--)
{
f[j] = max(f[j], f[j - b[i]] + a[i]);
}
cout << f[w];
return 0;
}