题目:
http://acm.hdu.edu.cn/showproblem.php?pid=1074题意:
给出一些科目作业的完成所需时间和最后期限,每比最后期限晚1天交就要减一学分,求如何安排写作业能够让被减的学分尽可能的少。
思路:
简单状压dp,数据很小所以开一个dp结构体,包含t,s,pos,res[16]就是在i状态时所需时间,最小扣分,已写作业数,写作业顺序。
然后状压0到(1<<n)枚举所有状态的下一个状态更新就行了。复杂度(1<<n)*n;
代码:
#define INF 0x3f3f3f3f
#define N 112345
#define M 112
int n,m;
int flag,sum,ave,ans,res,len,ans1,ans2;
int a[M],b[M];
char s[M][101];
struct node
{
int t,s;
int res[16],pos;
}dp[N];
int main()
{
int i,j,k,kk,t,x,y,z;
scanf("%d",&k);
while(k--)
{
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%s%d%d",&s[i],&a[i],&b[i]);
for(i=0;i<=(1<<n);i++)
dp[i].s=INF;
dp[0].t=dp[0].s=dp[0].pos=0;
for(i=0;i<(1<<n);i++)
for(j=0;j<n;j++)
{
t=(1<<j);
if(t&i)continue;
x=t|i;
dp[x].t=dp[i].t+b[j];
dp[x].pos=dp[i].pos+1;
t=max(dp[x].t-a[j],0);
if(dp[i].s+t<dp[x].s)
{
dp[x].s=dp[i].s+t;
memcpy(dp[x].res,dp[i].res,sizeof(dp[i].res));
dp[x].res[dp[x].pos]=j;
}
}
t=(1<<n)-1;
printf("%d\n",dp[t].s);
for(i=1;i<=dp[t].pos;i++)
printf("%s\n",s[dp[t].res[i]]);
}
return 0;
}