Title:
Given several groups of backpacks, each group has a corresponding type, (take at least one, take at most, take arbitrarily), each item can only be taken once, and calculate the maximum value that meets the conditions.
Analysis:
As long as I remind myself to remember the three ways of writing backpacks, I really understand them,
Note that at least one and two judgment conditions can not be interchanged, because there may be a situation of 0, so the exchange may cause an item to be taken twice.
It can't be written at most onceBecause maybe the maximum dp[x][v] of that item has been calculated before, but it is not considered in the next calculation.
#include<bits/stdc++.h> using namespace std; const int maxn=105; int n,T,m; struct node{ int c,g; node(int c,int g):c(c),g(g){} node(){} }; vector<node> p[maxn]; int s[maxn]; int dp[maxn][maxn]; void least(int x){ for(int i=0;i<p[x].size();i++){ for(int v=T;v>=p[x][i].c;v--){ if(dp[x][v-p[x][i].c]!=-1){ dp[x][v]=max(dp[x][v],dp[x][v-p[x][i].c]+p[x][i].g); } if(dp[x-1][v-p[x][i].c]!=-1){ dp[x][v]=max(dp[x][v],dp[x-1][v-p[x][i].c]+p[x][i].g); } } } } void most(int x){ for(int i=0;i<=T;i++){ dp[x][i]=dp[x-1][i]; } for(int i=0;i<p[x].size();i++){ for(int v=T;v>=p[x][i].c;v--){ if(dp[x-1][v-p[x][i].c]!=-1) dp[x][v]=max(dp[x][v],dp[x-1][v-p[x][i].c]+p[x][i].g); } } } void free(int x){ for(int i=0;i<=T;i++){ dp[x][i]=dp[x-1][i]; } for(int i=0;i<p[x].size();i++){ for(int v=T;v>=p[x][i].c;v--){ if(dp[x][v-p[x][i].c]!=-1) dp[x][v]=max(dp[x][v],dp[x][v-p[x][i].c]+p[x][i].g); } } } int main(){ while(scanf("%d%d",&n,&T)!=EOF){ for(int i=1;i<=n;i++){ p[i].clear(); } for(int i=1;i<=n;i++){ scanf("%d%d",&m,&s[i]); for(int j=1;j<=m;j++){ int c,g; scanf("%d%d",&c,&g); p[i].push_back(node(c,g)); } } memset(dp,-1,sizeof dp); for(int i=0;i<=T;i++){ dp[0][i]=0; } for(int i=1;i<=n;i++){ if(s[i]==0){ least(i); }else if(s[i]==1){ most(i); }else free(i); } printf("%d\n",dp[n][T]); } return 0; }