dp,麻煩的是需要字典序最小,每次更新dp需要進行判斷。
#define _CRT_SECURE_NO_WARNINGS
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int N = 15 + 5;
struct Course {
char s[50 + 5];
int ed, time;
bool operator<(const Course& c)const {
return strcmp(s, c.s) < 0;
}
}cor[N];
int dp[1 << 20], pre[1 << 20];
void print(int x, vector<int>& v) {
if (x == 0) return;
print((1 << pre[x]) ^ x, v);
v.push_back(pre[x]);
}
int big(vector<int> a, vector<int> b) {
for (int i = 0; i < a.size(); i++){
if (a[i] > b[i]) return 1;
if (a[i] < b[i]) return 0;
}
return 0;
}
int main() {
int t; scanf("%d", &t);
while (t--) {
int n; scanf("%d", &n);
for (int i = 0; i < n; i++)
scanf("%s%d%d", cor[i].s, &cor[i].ed, &cor[i].time);
sort(cor, cor + n);
for (int i = 0; i < (1 << n); i++)
dp[i] = 1e7;
dp[0] = 0;
for (int i = 0; i < (1 << n); i++) {
int pret = 0;
for (int j = 0; j < n; j++)
if ((i >> j) & 1)
pret += cor[j].time;
for (int j = 0; j < n; j++)
if (!((i >> j) & 1))
{
int now = dp[i] + (cor[j].ed < pret + cor[j].time ? cor[j].time + pret - cor[j].ed : 0);
if (now < dp[(1 << j) + i]) {
dp[(1 << j) + i] = now;
pre[(1 << j) + i] = j;
}
else if (now == dp[(1 << j) + i]) {
vector<int> v1, v2;
print((1 << j) + i,v1);
print(i, v2);
v2.push_back(j);
if(big(v1,v2)) pre[(1 << j) + i] = j;
}
}
}
printf("%d\n", dp[(1 << n) - 1]);
vector<int> path;
print((1 << n) - 1, path);
for (int i = 0; i < path.size(); i++)
printf("%s\n", cor[path[i]].s);
}
return 0;
}