main.cc 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include <algorithm>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <vector>
  5. using namespace std;
  6. const int L = 51;
  7. const int N = 15;
  8. const int INF = 1 << 30;
  9. struct Project {
  10. char s[L];
  11. int d;
  12. int c;
  13. };
  14. Project pro[N];
  15. struct Dp {
  16. int pre; // Previous node
  17. int cur; // Current node
  18. int min; // Minimum score
  19. int fin; // The finish date
  20. };
  21. Dp dp[1 << N];
  22. vector<int> get_path(int i) {
  23. vector<int> path;
  24. while (i) {
  25. path.push_back(dp[i].cur);
  26. i = dp[i].pre;
  27. }
  28. reverse(path.begin(), path.end());
  29. return path;
  30. }
  31. int main() {
  32. int t, n;
  33. scanf("%d", &t);
  34. while (t--) {
  35. scanf("%d", &n);
  36. for (int i = 0; i < n; i++) // Don't neet to add & for pro[i].s
  37. scanf("%s %d %d", pro[i].s, &pro[i].d, &pro[i].c);
  38. dp[0].min = 0;
  39. dp[0].fin = 0;
  40. dp[0].pre = -1;
  41. int fin = (1 << n) - 1;
  42. // dp[i] = dp[i ^ (1 << k)] + min{score(i, k): k in i}
  43. for (int i = 1; i <= fin; i++) {
  44. dp[i].min = INF;
  45. for (int j = 0, j_ = 1; j < n; j++, j_ <<= 1) {
  46. if (i & j_) {
  47. int pre = i ^ j_;
  48. int tmp_fin = dp[pre].fin + pro[j].c;
  49. int tmp_min = tmp_fin - pro[j].d;
  50. tmp_min = max(0, tmp_min);
  51. if (dp[pre].min + tmp_min < dp[i].min) {
  52. dp[i].pre = pre;
  53. dp[i].cur = j;
  54. dp[i].min = dp[pre].min + tmp_min;
  55. dp[i].fin = tmp_fin;
  56. }
  57. // Get the path which has smaller lexicographic order.
  58. if (dp[pre].min + tmp_min == dp[i].min) {
  59. vector<int> p1 = get_path(dp[i].pre);
  60. vector<int> p2 = get_path(pre);
  61. if (p2 < p1) {
  62. dp[i].pre = pre;
  63. dp[i].cur = j;
  64. dp[i].fin = tmp_fin;
  65. }
  66. }
  67. }
  68. }
  69. }
  70. printf("%d\n", dp[fin].min);
  71. vector<int> path = get_path(fin);
  72. for (int i : path) printf("%s\n", pro[i].s);
  73. }
  74. return 0;
  75. }