稍微能理解一些了,至少取一个的分组背包。
http://www.cnblogs.com/wuyiqi/archive/2011/11/19/2255208.html
写hdu3033的那题 网上没有解释好一点的题解 ,这题题解比较多
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int N,T,M,S,w,v;
int dp[110],DP[110];
int main()
{
int i,j,k;
while(scanf("%d%d",&N,&T)!=EOF)
{
memset(dp,-1,sizeof(dp)); dp[0]=0;
for(i=1;i<=N;i++)
{
scanf("%d%d",&M,&S);
if(S==0) //至少1个
{int DP[110]; memset(DP,-1,sizeof(DP));
for(j=1;j<=M;j++){
scanf("%d%d",&w,&v);
for(k=T;k>=w;k--){
if(DP[k-w]!=-1&&DP[k]<DP[k-w]+v) DP[k]=DP[k-w]+v;
if(dp[k-w]!=-1&&DP[k]<dp[k-w]+v) DP[k]=dp[k-w]+v;
}
}
for(k=0;k<=T;k++) dp[k]=DP[k];
}
else if(S==1) //最多一个
{
for(j=0;j<=T;j++) DP[j]=dp[j];
for(k=1;k<=M;k++)
{
scanf("%d%d",&w,&v);
for(j=T;j>=w;j--)
if(dp[j-w]!=-1&&DP[j]<dp[j-w]+v) DP[j]=dp[j-w]+v;
}
for(j=0;j<=T;j++) dp[j]=DP[j];
}
else //01背包
{
for(j=1;j<=M;j++){
scanf("%d%d",&w,&v);
for(k=T;k>=w;k--) if(dp[k-w]!=-1&&dp[k]<dp[k-w]+v) dp[k]=dp[k-w]+v;
}
}
}
for(k=-1,i=0;i<=T;i++) if(k<dp[i]) k=dp[i];
printf("%d\n",k);
}
return 0;
}