很简单的题目,把输入的字符串排序以保证字典序最小,再开一个数组记录路径就ok。
ACcode:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int NS=16;
const int INF=1<<30;
struct homework
{
string w;
int d,c;
bool operator <(const homework cmp) const{
return w<cmp.w;
}
}h[NS];
int n;
int dp[1<<NS],day[1<<NS],pos[1<<NS];
int gettime(int x)
{
int ans=0;
for (int i=0;x>0;x>>=1,i++)
if (x&1) ans+=h[i].c;
return ans;
}
void print(int x)
{
if (x<=0) return ;
print(pos[x]);
for (int i=0;i<n;i++)
if (x&(1<<i)&&(pos[x]&(1<<i))==0)
{
x=i;
break;
}
cout<<h[x].w<<endl;
}
int main()
{
char ch[110];
int T,x,y,z,t,lim;
scanf("%d",&T);
while (T--)
{
scanf("%d",&n);
for (int i=0;i<n;i++)
{
scanf("%s%d%d",ch,&x,&y);
h[i].w=(string)ch,h[i].d=x,h[i].c=y;
}
sort(h,h+n),lim=(1<<n)-1;
for (int i=0;i<=lim;i++)
{
dp[i]=INF,pos[i]=-1;
day[i]=gettime(i);
}
dp[0]=0;
for (int i=1;i<=lim;i++)
{
for (int j=n-1;j>=0;j--)
{
if (i&(1<<j))
{
t=i-(1<<j),y=dp[t];
if (y>=INF) continue;
if (day[i]>h[j].d) y+=day[i]-h[j].d;
if (dp[i]>y)
{
dp[i]=y;
pos[i]=t;
}
}
}
}
printf("%d\n",dp[lim]);
print(lim);
}
return 0;
}