#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAX_DAY 200
#define MAX_STATUS 65536
#define MAX 0x7ffffff
char course[20][105];
int deadline[20], needtime[20];
int dp[MAX_STATUS], curday[MAX_STATUS], last[MAX_STATUS];
void pretreat(int maxstatus, int N) {
int i, j, yw;
memset(curday, 0, sizeof(int) * (maxstatus + 1));
for (i = 0; i <= maxstatus; i++) {
for (j = 0; j < N; j++) {
yw = 1 << j;
if (i & yw) {
curday[i] += needtime[j];
}
}
}
}
void printpath(int curstatus) {
int temp, k;
if(curstatus == 0) {
return ;
}
printpath(last[curstatus]);
temp = curstatus - last[curstatus];
k = 0;
while(temp > 1) {
k++;
temp >>= 1;
}
puts(course[k]);
}
int main() {
int T, N;
int i, j, maxstatus, temp, yw;
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
scanf("%d", &T);
while (T--) {
scanf("%d", &N);
maxstatus = 1 << N;
maxstatus--;
for (i = 0; i < N; i++) {
scanf("%s %d %d", course[i], &deadline[i], &needtime[i]);
}
pretreat(maxstatus, N);
dp[0] = 0;
last[0] = 0;
for (i = 1; i <= maxstatus; i++) {
dp[i] = MAX;
last[i] = MAX;
for (j = 0; j < N; j++) {
yw = 1 << j;
if (yw & i) {
temp = curday[i] - deadline[j];
if (temp < 0) {
temp = 0;
}
temp += dp[i - yw];
if (dp[i] >= temp) {
dp[i] = temp;
if (last[i] > i - yw) {
last[i] = i - yw;
}
}
}
}
}
printf("%d\n", dp[maxstatus]);
printpath(maxstatus);
}
return 0;
}
这题花了我好久才想明白,开始的时候用二维数组存储,超空间,后来才想到这种一维的方法。不过虽然已经AC了,我还是有一点没有明白,
就是输出路径的时候我只在每一种状态上记录了前一种状态,最后回溯输出,但我还不确定这样做是对的。路过的大牛帮我想想,指点一下我哈。