每次用一个 f [ i , j ] f[i, j] f[i,j],然后去枚举一下这一组的每一个物品,分别计算选每一个的值然后每次取最大值,在此之前先赋初值为不选的值也就是 f [ i − 1 , j ] f[i - 1, j] f[i−1,j],然后去比较选的最大值,但是如果是一维滚动数组的话则不需要有这一步,不赋值时就是不选的价值。
//一维
// #include <iostream>
// #include <cstring>
// #include <algorithm>
// using namespace std;
// const int N = 1005;
// int n, m;
// int f[N], v[N][N], w[N][N], s[N];
// int main()
// {
// cin >> n >> m;
// for (int i = 1; i <= n; i ++ )
// {
// cin >> s[i];
// for (int j = 1; j <= s[i]; j ++ )
// {
// cin >> v[i][j] >> w[i][j];
// }
// for (int j = m; j >= 0; j -- )
// {
// for (int k = 0; k <= s[i]; k ++ )//枚举一下这一组里的所有物品,看看加哪个多,因为去掉当前物品后的体积是没有更新过的
// {
// if (j >= v[i][k]) f[j] = max(f[j], f[j - v[i][k]] + w[i][k]);
// }
// }
// }
// cout << f[m];
// return 0;
// }
//二维
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1005;
int n, m;
int f[N][N], v[N][N], w[N][N], s[N];
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
{
cin >> s[i];
for (int j = 1; j <= s[i]; j ++ )
{
cin >> v[i][j] >> w[i][j];
}
for (int j = 0; j <= m; j ++ )
{
f[i][j] = f[i - 1][j]; //不选
for (int k = 0; k <= s[i]; k ++ )//枚举一下这一组里的所有物品,看看加哪个多,因为去掉当前物品后的体积是没有更新过的
{
if (j >= v[i][k]) f[i][j] = max(f[i][j], f[i - 1][j - v[i][k]] + w[i][k]);
}
}
}
cout << f[n][m];
return 0;
}
每组物品放进来枚举,用的是上一层的数据,所以不会出现串联。