题目大意:
现在又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; }