- 题目链接
- 题目大意:给出作业和截止时间以及完成作业花费的时间,晚于截止时间一天就减一分,最后最少减多少分
- 用二进制表示所有状态
- AC代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<stack>
#include<string>
using namespace std;
struct
{
string name;
int cost,dead;
}object[30];
struct
{
int time,score,pre,now;
}dp[1<<16];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
cin>>object[i].name>>object[i].dead>>object[i].cost;
int end=1<<n;
for(int i=1;i<end;i++)//现态
{
dp[i].score=1000000000;
for(int j=0;j<n;j++)
{
int temp=1<<j;
if(temp&i)
{
int past=i-temp;
int grade=max(dp[past].time+object[j].cost-object[j].dead,0);
if(dp[i].score>=grade+dp[past].score)//j从0开始这里必须有=,要是从n-1开始就没有=
{
dp[i].score=grade+dp[past].score;
dp[i].time=dp[past].time+object[j].cost;
dp[i].pre=past;
dp[i].now=j;
}
}
}
}
printf("%d\n",dp[end-1].score);
stack<int> s;
int t=end-1;
while(t)
{
s.push(dp[t].now);
t=dp[t].pre;
}
while(!s.empty())
{
cout<<object[s.top()].name<<endl;
s.pop();
}
}
return 0;
}