http://acm.hdu.edu.cn/showproblem.php?pid=3535
对于第一种分组 先将该组dp数组初始化 再从上一组转移过来 先初始化的原因就是 因为该组至少拿一个物品 所以那些无法用该组物品拼凑的重量对应的价值也就没意义了
第二种是裸的分组背包 第三种是裸的01背包
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e2+10;
int w[maxn],v[maxn];
int dp[maxn][maxn];
int n,s;
int main()
{
int i,j,k,m,tp;
while(scanf("%d%d",&n,&s)!=EOF){
memset(dp,-1,sizeof(dp));
memset(dp[0],0,sizeof(dp[0]));
for(i=1;i<=n;i++){
scanf("%d%d",&m,&tp);
for(j=1;j<=m;j++){
scanf("%d%d",&w[j],&v[j]);
}
if(tp==0){
for(j=1;j<=m;j++){
for(k=s;k>=w[j];k--){
if(dp[i][k-w[j]]!=-1) dp[i][k]=max(dp[i][k],dp[i][k-w[j]]+v[j]);
if(dp[i-1][k-w[j]]!=-1) dp[i][k]=max(dp[i][k],dp[i-1][k-w[j]]+v[j]);
}
}
}
else if(tp==1){
for(j=0;j<=s;j++){
dp[i][j]=dp[i-1][j];
}
for(j=1;j<=m;j++){
for(k=s;k>=w[j];k--){
if(dp[i-1][k-w[j]]!=-1) dp[i][k]=max(dp[i][k],dp[i-1][k-w[j]]+v[j]);
}
}
}
else{
for(j=0;j<=s;j++){
dp[i][j]=dp[i-1][j];
}
for(j=1;j<=m;j++){
for(k=s;k>=w[j];k--){
if(dp[i][k-w[j]]!=-1) dp[i][k]=max(dp[i][k],dp[i][k-w[j]]+v[j]);
}
}
}
}
printf("%d\n",dp[n][s]);
}
return 0;
}