状态压缩,因为每个物品最多只有5个,直接十进制表示状态即可,建立一个hash表对应物品编号的权重,转化为无限背包即可。
/*
ID: jinusac1
PROG: shopping
LANG: C++
*/
#include <iostream>
#include <cstdio>
using namespace std;
struct goods{
int cost;//花费
int num;//各项物品数
}g[120];
int ss[1000]={0},w=1,size=0;
int dp[60000]={0};
int main()
{
freopen("shopping.in","r",stdin);
freopen("shopping.out","w",stdout);
int S;
cin>>S;
for(int i=1;i<=S;i++){
int n,num=0;
cin>>n;
for(int j=1;j<=n;j++){
int c,k;
cin>>c>>k;
if(!ss[c]) {ss[c]=w;w*=10;}
num+=(k*ss[c]);
}
int v;
cin>>v;
g[size].num=num;g[size].cost=v;
size++;
}
int n,tar=0;
cin>>n;
for(int i=1;i<=n;i++){
int c,k,cost,num=0;
cin>>c>>k>>cost;
if(!ss[c]) {ss[c]=w;w*=10;}
num=ss[c];
tar+=k*num;
g[size].num=num;g[size].cost=cost;size++;
}
for(int i=0;i<size;i++){
if(!dp[g[i].num]||(dp[g[i].num]>g[i].cost)) dp[g[i].num]=g[i].cost;
int t;
for(int j=1;j<=tar;j++) if(dp[j]&&((t=j+g[i].num)<=tar)){
if(dp[t]==0||((dp[j]+g[i].cost)<dp[t])) dp[t]=dp[j]+g[i].cost;
}
}
cout<<dp[tar]<<endl;
return 0;
}