//状态压缩 DP
//我勒个去 入门题卡了我两天
// dp[i]用i的二进制表示一种状态 例如:i=3 0011表示第0个和第1个物品在集合中 第2个和第3个物品不在集合中
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
#define N 16
struct node
{
char name[110];
int dl;
int cost;
}km[N];
#define inf 0x7fffffff
int line[1<<N];
int dp[1<<N];
int n,limit;
void init()
{
scanf("%d",&n);
int i;
for(i=0;i<n;i++)
{
scanf("%s %d %d",km[i].name,&km[i].dl,&km[i].cost);
}
limit=1<<n;
for(i=0;i<limit;i++)
dp[i]=inf;
dp[0]=0;
memset(line,-1,sizeof(line));
}
int add(int m,int k)
{
int top,cur,i;
top=cur=0;
for(i=0;i<n;i++)
{
if(m&(1<<i))
top+=km[i].cost;
}
cur=top-km[k].cost;
m=m-(1<<k);
int s=0;
for(i=0;i<n;i++)
{
if(!(m&(1<<i)))
{
if(km[i].dl<top)
{
s+=(top-cur)<(top-km[i].dl)?(top-cur):(top-km[i].dl);
}
}
}
return s;
}
void zt_dp()
{
int i,j,k,ad;
for(i=0;i<limit;i++)
{
for(j=0;j<n;j++)//求出dp[i]的最小值 即以i集合中的每个元素为最后加入集合的元素就出扣分最少的
{
if(i&(1<<j))//判断第j个元素是否在i集合中
{
ad=add(i,j);
if(dp[i-(1<<j)]+ad<dp[i])
{
dp[i]=dp[i-(1<<j)]+ad;
line[i]=j;
}
if(dp[i-(1<<j)]+ad==dp[i])//保证输出时是字典顺序
{
line[i]=j;
}
}
}
}
}
void print()
{
int index;
printf("%d\n",dp[limit-1]);
stack<int>q;
index=limit-1;
while(index!=0)
{
q.push(line[index]);
index=index-(1<<line[index]);
}
while(!q.empty())
{
printf("%s\n",km[q.top()].name);
q.pop();
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
zt_dp();
print();
}
return 0;
}
//我勒个去 入门题卡了我两天
// dp[i]用i的二进制表示一种状态 例如:i=3 0011表示第0个和第1个物品在集合中 第2个和第3个物品不在集合中
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
#define N 16
struct node
{
char name[110];
int dl;
int cost;
}km[N];
#define inf 0x7fffffff
int line[1<<N];
int dp[1<<N];
int n,limit;
void init()
{
scanf("%d",&n);
int i;
for(i=0;i<n;i++)
{
scanf("%s %d %d",km[i].name,&km[i].dl,&km[i].cost);
}
limit=1<<n;
for(i=0;i<limit;i++)
dp[i]=inf;
dp[0]=0;
memset(line,-1,sizeof(line));
}
int add(int m,int k)
{
int top,cur,i;
top=cur=0;
for(i=0;i<n;i++)
{
if(m&(1<<i))
top+=km[i].cost;
}
cur=top-km[k].cost;
m=m-(1<<k);
int s=0;
for(i=0;i<n;i++)
{
if(!(m&(1<<i)))
{
if(km[i].dl<top)
{
s+=(top-cur)<(top-km[i].dl)?(top-cur):(top-km[i].dl);
}
}
}
return s;
}
void zt_dp()
{
int i,j,k,ad;
for(i=0;i<limit;i++)
{
for(j=0;j<n;j++)//求出dp[i]的最小值 即以i集合中的每个元素为最后加入集合的元素就出扣分最少的
{
if(i&(1<<j))//判断第j个元素是否在i集合中
{
ad=add(i,j);
if(dp[i-(1<<j)]+ad<dp[i])
{
dp[i]=dp[i-(1<<j)]+ad;
line[i]=j;
}
if(dp[i-(1<<j)]+ad==dp[i])//保证输出时是字典顺序
{
line[i]=j;
}
}
}
}
}
void print()
{
int index;
printf("%d\n",dp[limit-1]);
stack<int>q;
index=limit-1;
while(index!=0)
{
q.push(line[index]);
index=index-(1<<line[index]);
}
while(!q.empty())
{
printf("%s\n",km[q.top()].name);
q.pop();
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
init();
zt_dp();
print();
}
return 0;
}