本菜表示开始做的时候完全不会啊。。。然后之后貌似听到听ZRY大神说什么状态压缩DP,然后就又想了1天,还是不会。。。然后搜索了一下,各种看不懂。。。只看到一句话,全部枚举。全部?不会超时?我真心太菜了,想了很久很久。。。终于搞懂了。。。
然后各种栈溢出,发现数组开小了。。。然后就开暴力了点。。。太不仔细了,切记切记
---------继续在ACM的道路上爬行。。。
#include<stdio.h>
#include<stdlib.h>
struct xx
{
char name[105];
int d,c;
}sub[20];
struct xxx
{
int path[20],cost,time;
}dp[1<<16];
int main()
{
int i,j,t,k,x,n,head,tail,que[1<<16],temp;
scanf("%d",&t);
while(t>0)
{
t--;
memset(dp,-1,sizeof(dp));
memset(que,0,sizeof(que));
scanf("%d",&n);
head=0;tail=-1;
for(i=1;i<=n;i++)
{
scanf(" %s%d%d",sub[i].name,&sub[i].d,&sub[i].c);
tail++;k=1<<(i-1);que[tail]=k;
dp[k].path[0]=1;
dp[k].path[1]=i;
dp[k].time=sub[i].c;
temp=sub[i].d-dp[k].time;
if(temp>=0)dp[k].cost=0;
else dp[k].cost=-temp;
}
while(head<=tail)
{
k=que[head];
head++;
for(i=1;i<=n;i++)
{
j=1<<(i-1);
if((j&k)!=0)continue;
x=j+k;
temp=sub[i].d-(dp[k].time+sub[i].c);
if(temp>=0)temp=0;
if(dp[x].time==-1||dp[x].cost>dp[k].cost-temp)
{
if(dp[x].time==-1){tail++;que[tail]=x;}
dp[x].time=dp[k].time+sub[i].c;
dp[x].cost=dp[k].cost-temp;
for(j=0;j<=dp[k].path[0];j++)dp[x].path[j]=dp[k].path[j];
dp[x].path[0]++;
dp[x].path[j]=i;
}
}
}
k=0;
for(i=1;i<=n;i++)k+=1<<(i-1);
printf("%d\n",dp[k].cost);
for(i=1;i<=n;i++)
printf("%s\n",sub[dp[k].path[i]].name);
}
return 0;
}