该题属于混合背包问题,而且还带分组。。。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF=-0xfffff;
const int NUM=120;
int dp[NUM][NUM],cost[NUM],v[NUM];
template <typename T>
T Max(T a,T b)
{
return (a>b)?(a):(b);
}
template <typename T>
T Max(T a,T b,T c)
{
return (a>Max(b,c))?(a):(Max(b,c));
}
int main()
{
int n,total;
while(cin>>n>>total)
{
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
int m,t;
scanf("%d%d",&m,&t);
for(int j=0;j<m;j++)
scanf("%d%d",&cost[j],&v[j]);
if(t==0)
{
for(int k=0;k<=total;k++) dp[i][k]=INF; //保证肯定选择一项工作
for(int j=0;j<m;j++)
for(int k=total;k>=cost[j];k--)
dp[i][k]=Max(dp[i][k],dp[i-1][k-cost[j]]+v[j],dp[i][k-cost[j]]+v[j]);
}
else if(t==1)
{
for(int k=0;k<=total;k++) dp[i][k]=dp[i-1][k];
for(int j=0;j<m;j++)
for(int k=total;k>=cost[j];k--)
dp[i][k]=Max(dp[i][k],dp[i-1][k-cost[j]]+v[j]);
}
else
{
for(int k=0;k<=total;k++) dp[i][k]=dp[i-1][k];
for(int j=0;j<m;j++)
for(int k=total;k>=cost[j];k--)
dp[i][k]=Max(dp[i][k],dp[i-1][k-cost[j]]+v[j],dp[i][k-cost[j]]+v[j]);
}
}
int flag=Max(dp[n][total],-1);
printf("%d\n",flag);
}
return 0;
}