#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int M=6;
const int inf=20000;
/*
这个题太妙了,因为每种商品的数量不超过5 这就可以很妙的利用一个六进制的数来记录相应的每种物品的数量,余数为1-5正好合适
动太规划每次都能给人带来太多的惊喜!
题目链接:http://poj.org/problem?id=1170
*/
const int base[6]={1,6,36,216,1296,7776};
struct Offer{
int st;
int price;
Offer(){
st=0;
price=0;
}
};
struct Item{
int cnt;
int p;
};
int n,m,id,state;
Offer offer[101];
Item item[5];
int hash[1000];
int dp[10000];
bool check(int x,int y){//检查一下五种物品的x状态和y状态是否满足各种物品的数量都符合给定物品的数量 即小于等于 如果超出了显然不是有效状态
for(int i=0;i<n;i++){
if((x%6+y%6)>item[i].cnt){
return false;
}
x/=6;
y/=6;
}
return true;
}
int calculate(int state){//求不用套餐时状态为state时的花费
int cost=0;
for(int i=0;state;i++){
cost+=(state%6)*item[i].p;//一看就能明白,这就是取出各种物品的数量然后乘上单价
state/=6;
}
return cost;
}
int min(int a,int b){
return a<b?a:b;
}
int main(){
int i,j,k,code,cnt,cost,p;
state=0;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d%d%d",&code,&item[i].cnt,&item[i].p);
hash[code]=i;
state+=base[i]*item[i].cnt;
}
scanf("%d",&m);
for(i=0;i<m;i++){
scanf("%d",&p);
for(j=0;j<p;j++){
scanf("%d%d",&code,&cnt);
offer[i].st+=base[hash[code]]*cnt;
}
scanf("%d",&offer[i].price);
}
for(i=0;i<=state;i++)dp[i]=inf;
dp[0]=0;//这个地方当state为0时即各种东西数量都为0 一定要注意初始化 因为这个地方调了很长时间都没发现
for(i=0;i<m;i++){//遍历各种套餐,看看加套餐和不加套餐的情况下相同数量相同产品那个花费更低
for(j=0;j<=state;j++){
if(dp[j]==inf)continue;
if(j+offer[i].st<=state && check(j,offer[i].st)){
if(dp[j+offer[i].st]>dp[j]+offer[i].price){
dp[j+offer[i].st]=dp[j]+offer[i].price;
}
}
}
}
int ans=inf,temp;
for(i=0;i<=state;i++){//遍历各种东状态一部分用套餐一部分不用套餐时的花费,找最小的
temp=calculate(state-i);
ans=min(temp+dp[i],ans);
}
printf("%d\n",ans);
return 0;
}