题意:
给出n组数据,每组数据有一个类型。
0代表至少选择一个,1代表至多选择一个,2代表任意选择。
给出背包容量。
如果背包不能满足最基本的要求输出-1。
思路:
背包问题变相考察~
当0的时候初始化为-INF,然后就能保证至少选择一个。
当1或2的时候初始化上一层的值,然后1和2稍微有点区别,1只能从上一层得到下一层,2可以用本层更新。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int c[105],w[105]; int dp[105][105]; int main() { int n,t; while(scanf("%d%d",&n,&t)!=EOF) { memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) { int m,s; scanf("%d%d",&m,&s); for(int j=1;j<=m;j++) { scanf("%d%d",&w[j],&c[j]); } if(s==0) { for(int j=0;j<=t;j++) { dp[i][j]=-999999999; } for(int j=1;j<=m;j++) { for(int k=t;k>=w[j];k--) { //dp[i][k]=max(dp[i][k],dp[i-1][k-w[j]]+c[j]); //dp[i][k]=max(dp[i][k],dp[i][k-w[j]]+c[j]); dp[i][k]=max(dp[i][k],max(dp[i-1][k-w[j]]+c[j],dp[i][k-w[j]]+c[j])); } } } else if(s==1) { for(int j=0;j<=t;j++) { dp[i][j]=dp[i-1][j]; } for(int j=1;j<=m;j++) { for(int k=t;k>=w[j];k--) { dp[i][k]=max(dp[i][k],dp[i-1][k-w[j]]+c[j]); } } } else { for(int j=0;j<=t;j++) { dp[i][j]=dp[i-1][j]; } for(int j=1;j<=m;j++) { for(int k=t;k>=w[j];k--) { dp[i][k]=max(dp[i][k],dp[i][k-w[j]]+c[j]); } } } } if(dp[n][t]<0) printf("-1\n"); else printf("%d\n",dp[n][t]); } }