题目大意:
现在又n中不同的作业需要做,每种作业有一个上交期限可完成需要的时间,对于任何一门作业,超出那门作业的提交日期每一天那门课将会扣一分,求使得扣分最少的条件下应该如何安排写作业的顺序,输出写作业的顺序,如果有多组解那么输出字典序最小的方案
大致思路:
刚开始以为是个贪心的策略,后来发现不对,,,
这是个状态压缩DP对于每一门课的作业有两种状态,完成货没有完成,那么用dp[ i ] 表示当前作业状态( i 的二进制对应位置上式1或者0表示那门课是否完成) 这样
dp[ i ] = min( dp[ i 少一个 1 ] + 那门课的罚时)
很基础的一个状态压缩dp
代码如下:
Result : Accepted Memory : 716 KB Time : 15 ms
/*
* Author: Gatevin
* Created Time: 2014/8/13 20:50:48
* File Name: haha.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
typedef long long lint;
const int inf = 0x7fffffff;
struct subj
{
int C,D;
string name;
subj(int c, int d, string s) : C(c) , D(d), name(s){}
subj(){}
};
subj sub[20];
int dp[1 << 16];
int pre[1 << 16];
int cost[1 << 16];
vector <int> answer;
int main()
{
int t,n;
int c,d;
string s;
cin>>t;
while(t--)
{
cin>>n;
for(int i = 0; i < n; i++)
{
cin>>s>>d>>c;
sub[i] = subj(c,d,s);
}
for(int i = 1; i <= (1 << n) - 1; i++)
{
dp[i] = inf;
}
dp[0] = 0;
cost[0] = 0;
for(int i = 0; i <= (1 << n) - 1; i++)
{
for(int j = 0; j < n; j++)
{
int tmp = 1 << j;
if(i & tmp)
{
cost[i] = cost[i & (~tmp)] + sub[j].C;
if(cost[i] > sub[j].D)
{
if(dp[i] >= dp[i & (~tmp)] + cost[i] - sub[j].D)
{
dp[i] = dp[i &(~tmp)] + cost[i] - sub[j].D;
if(dp[i] == dp[i & (~tmp)] + cost[i] - sub[j].D)
{
if(sub[j].name < sub[pre[i]].name)
{
pre[i] = j;
continue;
}
}
pre[i] = j;
}
}
else
{
if(dp[i] >= dp[i & (~tmp)])
{
dp[i] = dp[i & (~tmp)];
if(dp[i] == dp[i & (~tmp)])
{
if(sub[j].name < sub[pre[i]].name)
{
pre[i] = j;
continue;
}
}
pre[i] = j;
}
}
}
}
}
cout<<dp[(1 << n) - 1]<<endl;
int now = (1 << n) - 1;
while(now != 0)
{
answer.push_back(pre[now]);
now = now & (~(1 << pre[now]));
}
for(unsigned int k = answer.size() - 1; k < answer.size(); k--)
{
cout<<sub[answer[k]].name<<endl;
}
answer.clear();
}
return 0;
}