题意: 有n份作业需要做,每一份作业都有 一个截至时间和一个耗时(完成该作业需要的时间),每份作业每逾期一天就扣掉一分,要求完成所有作业并扣掉最少的学分,
并把完成作业的顺序输出出来!
#include<cstring>
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int N=1<<16;
int dp[N],sum[N],pre[N],n,m,t,c[19],d[19]; //pre记录前驱状态,sum记录当前天数
char name[19][111];
void prin(int x)
{
int y=pre[x];
int tem=x-y;
if(y)
prin(y);
for(int i=0;i<n;i++)
{
if(tem&(1<<i))
printf("%s\n",name[i]);
}
}
int main()
{
int tA;
scanf("%d",&tA);
while(tA--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf(" %s%d%d",&name[i],&c[i],&d[i]);
}
memset(dp,0x3f,sizeof(dp));
memset(sum,0,sizeof(sum));
memset(pre,0,sizeof(pre));
dp[0]=0;
t=1<<n;
for(int s=0;s<t;s++)
{
if(dp[s]==INF)continue;
for(int j=0;j<n;j++)
{
if(s&(1<<j))continue;
int ret=dp[s]+max(sum[s]+d[j]-c[j],0),st=s|(1<<j);
if(dp[st]>ret)
{
dp[st]=ret;
sum[st]=sum[s]+d[j];
pre[st]=s;
}
}
}
printf("%d\n",dp[t-1]);
prin(t-1);
}
return 0;
}