/*
用0表示这个hamber没做,1表示做了,那么可以用二进制表示对于hanmber
做了或没做的状态
那么状态转移方程 dp[curtemp]=max(dp[curtemp],dp[i]+hamber[j].value);
dp[i]表示在i状态下能得到的最大价值
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 20
#define maxs 1<<15
int dp[maxs];//dp[i]对于第i个状态能得到的最大值
vector<int> vec[maxn];
int n,e;
struct node
{
int value;
int energy;
}hamber[maxn];
int judge(int x)//判断是否符合能量不超过总能量的条件
{
int ans=0;
int pos=0;
while(x)
{
if(x%2)
ans+=hamber[pos].energy;
pos++;
x/=2;
}
return ans>e;
}
void DP()
{
int upper=1<<n;
int i,j,k;
memset(dp,-1,sizeof(dp));
dp[0]=0;
for(i=0;i<upper;i++)
{
if(dp[i]==-1)//判断这个状态能不能到达
continue;
for(j=0;j<n;j++)
{
int cur=1<<j;
if(cur&i) //判断第j个hamber是否已经做完
continue;
int curtemp=cur|i;
if(judge(curtemp)) //判断是否符合能量不超过总能量的条件
continue;
for(k=0;k<vec[j].size();k++)
{
int curk=1<<(vec[j][k]-1);
if(!(curk&i))
break;
}
if(k!=vec[j].size())//判断在做这个hamber之前的hamber是否已经做好
continue;
dp[curtemp]=max(dp[curtemp],dp[i]+hamber[j].value);
}
}
int ans=0;
for(i=0;i<upper;i++)
ans=max(ans,dp[i]);
printf("%d\n",ans);
}
int main()
{
int i,j,k;
int T;int Q;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&e);
for(i=0;i<n;i++)
scanf("%d",&hamber[i].value);
for(i=0;i<n;i++)
scanf("%d",&hamber[i].energy);
for(i=0;i<n;i++)
vec[i].clear();
for(i=0;i<n;i++)
{
scanf("%d",&Q);
int temp;
while(Q--)
{
scanf("%d",&temp);
vec[i].push_back(temp);
}
}
DP();
}
return 0;
}
用0表示这个hamber没做,1表示做了,那么可以用二进制表示对于hanmber
做了或没做的状态
那么状态转移方程 dp[curtemp]=max(dp[curtemp],dp[i]+hamber[j].value);
dp[i]表示在i状态下能得到的最大价值
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
#define maxn 20
#define maxs 1<<15
int dp[maxs];//dp[i]对于第i个状态能得到的最大值
vector<int> vec[maxn];
int n,e;
struct node
{
int value;
int energy;
}hamber[maxn];
int judge(int x)//判断是否符合能量不超过总能量的条件
{
int ans=0;
int pos=0;
while(x)
{
if(x%2)
ans+=hamber[pos].energy;
pos++;
x/=2;
}
return ans>e;
}
void DP()
{
int upper=1<<n;
int i,j,k;
memset(dp,-1,sizeof(dp));
dp[0]=0;
for(i=0;i<upper;i++)
{
if(dp[i]==-1)//判断这个状态能不能到达
continue;
for(j=0;j<n;j++)
{
int cur=1<<j;
if(cur&i) //判断第j个hamber是否已经做完
continue;
int curtemp=cur|i;
if(judge(curtemp)) //判断是否符合能量不超过总能量的条件
continue;
for(k=0;k<vec[j].size();k++)
{
int curk=1<<(vec[j][k]-1);
if(!(curk&i))
break;
}
if(k!=vec[j].size())//判断在做这个hamber之前的hamber是否已经做好
continue;
dp[curtemp]=max(dp[curtemp],dp[i]+hamber[j].value);
}
}
int ans=0;
for(i=0;i<upper;i++)
ans=max(ans,dp[i]);
printf("%d\n",ans);
}
int main()
{
int i,j,k;
int T;int Q;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&e);
for(i=0;i<n;i++)
scanf("%d",&hamber[i].value);
for(i=0;i<n;i++)
scanf("%d",&hamber[i].energy);
for(i=0;i<n;i++)
vec[i].clear();
for(i=0;i<n;i++)
{
scanf("%d",&Q);
int temp;
while(Q--)
{
scanf("%d",&temp);
vec[i].push_back(temp);
}
}
DP();
}
return 0;
}