这题个人觉得比较难,多种混合的背包。
s=0,该组中至少选一种,就和买鞋那题一样,该组的初始化为负无穷,保证不会出现不选的情况,状态转移方程:
dp[i][k]=Max(Max(dp[i][k-a[j]]+b[j],dp[i][k]),dp[i-1][k-a[j]]+b[j])。
s=1,该组中最多选一件,这样是基本的组合背包问题,用二维是为了方便复制上一层的结果作为本组的初始化。
s=2,改组随便选了,就是01背包,同样要复制上一层结果最为本层的初始化,不然前面的都白选了。
本题每层初始化的衔接有点难想。
代码:
#include<stdio.h> #include<string.h> int Max(int a,int b) { return a>b?a:b; } int main() { int n,t,m,s; int i,j,k; int a[110],b[110],dp[110][110]; while(scanf("%d%d",&n,&t)!=EOF) { memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { scanf("%d%d",&m,&s); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); for(j=1;j<=m;j++) scanf("%d%d",&a[j],&b[j]); if(s==0) { for(j=0;j<=t;j++) dp[i][j]=-0x7f7f7f7f; //dp[i][0]=0; for(j=1;j<=m;j++) { for(k=t;k>=a[j];k--) { dp[i][k]=Max(Max(dp[i][k-a[j]]+b[j],dp[i][k]),dp[i-1][k-a[j]]+b[j]); } } } else if(s==1) { for(j=0;j<=t;j++) dp[i][j]=dp[i-1][j]; for(j=1;j<=m;j++) for(k=t;k>=a[j];k--) { dp[i][k]=Max(dp[i-1][k-a[j]]+b[j],dp[i][k]); } } else { for(j=0;j<=t;j++) dp[i][j]=dp[i-1][j]; for(j=1;j<=m;j++) { for(k=t;k>=a[j];k--) { dp[i][k]=Max(dp[i][k-a[j]]+b[j],dp[i][k]); } } } } if(dp[n][t]<0) printf("-1\n"); else printf("%d\n",dp[n][t]); } return 0; }