#include<iostream> #include<string> #include<stdio.h> #define INF 0x3ffffff using namespace std; struct sj{ char name[50]; int deadline,cost; }sbj[20]; //dp[state][last]表示:(state 转变成二进制,1表示:剩下可选的, //0表示:已经被选走的)state状态下最后选last的扣分数, //因为作业最多有15个,所以 状态最多有2^15-1个状态 (2^15=32768) int dp[32768+10][15]; int n,mn; //acs[state][last]表示:state状态下最后选last的最优序列 //string acs[state][last] 下表从0到n-1保存的是作业的序号。如‘1’为 //第一个作业,':'为第10个作业 string acs[32768+10][15]; //state:当前状态,last:最后选的作业序号,cost:当前状态下 //做完剩余作业的日期,co:已扣分数 int dfs(int state,int last,int cost,int co) { int min=INF; int state_t=state&(~(1<<(last-1))); if(co>=mn) return INF; if(state_t==0) { dp[state][last]=(cost>sbj[last].deadline?cost-sbj[last].deadline:0); char s[3]; s[0]=last+'0'; s[1]='/0'; acs[state][last]=s; return dp[state][last]; } if(dp[state][last]) return dp[state][last]; for(int i=n-1;i>=0;i--) { int result=INF; int tmp=state_t&(~(1<<i)); if(tmp!=state_t) { result=dfs(state_t,i+1,cost-sbj[last].cost, (cost>sbj[last].deadline?cost-sbj[last].deadline:0)+co ) + (cost>sbj[last].deadline?cost-sbj[last].deadline:0); if(min>result) { min=result; char s[3]; s[0]=last+'0'; s[1]='/0'; acs[state][last]=acs[state_t][i+1]+s; } } } dp[state][last]=min; return min; } int main() { int t,cost; //freopen("hdu1074.in.txt","r",stdin); //freopen("hdu1074.out.txt","w",stdout); scanf("%d",&t); while(t--) { scanf("%d",&n); cost=0; int state=(1<<n)-1; for(int i=0;i<=state;i++) for(int j=0;j<=n;j++) dp[i][j]=0; for(int i=1;i<=n;i++) { scanf("%s%d%d",sbj[i].name,&sbj[i].deadline,&sbj[i].cost); cost+=sbj[i].cost; } mn=INF; int ii=0; for(int i=n;i>=1;i--) { int tt=dfs(state,i,cost,0); if(mn>tt) { ii=i; mn=tt; } } printf("%d/n",mn); for(int i=0;i<n;i++) printf("%s/n",sbj[acs[state][ii][i]-'0'].name); } return 0; }