#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
const int maxn = (1<<15)+10;
struct node {
int deadline;//截止时间
int how_day;//花费的时间
char name[110];
} nxt[20];
int dp[maxn];
int time[maxn];
int print[maxn];
void output(int x) { //打印路径 dfs
if(!x)
return;
output( x - (1<<print[x]) );
printf("%s\n", nxt[print[x]].name);//字典序
}
int main() {
freopen("data.in", "r", stdin);
int T, n;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%s %d %d", nxt[i].name, &nxt[i].deadline, &nxt[i].how_day);
int total = 1<<n;
memset(time, 0, sizeof(time));
memset(print, 0, sizeof(print));
memset(dp, 0, sizeof(dp));
//全排列问题,状压dp
for(int i = 1; i < total; i++) {
dp[i] = INF;
for(int j = n-1; j >= 0; j--) {
int temp = 1<<j;
if(!(i & temp))
continue;//没有写j门课的作业则跳出循环
int score = time[i-temp] + nxt[j].how_day - nxt[j].deadline;//扣得分数
score = max(score,0);//扣得分数不可能是负的
if(dp[i] > dp[i-temp] + score) { //如果当前状态可以更优则更新dp值,和time的值
dp[i] = dp[i-temp] + score;
time[i] = time[i-temp] + nxt[j].how_day;
print[i] = j;//修改路径
}
}
}
//所有课作业做完应该所有为都为1,就是1<<n-1
printf("%d\n", dp[total-1]);//输出扣得分数
output(total - 1);//打印路径
}
return 0;
}
hdu 1074 Doing Homework(状压DP)
猜你喜欢
转载自blog.csdn.net/ccshijtgc/article/details/82994133
今日推荐
周排行