hdu 1074 Doing Homework 状态压缩的DP

#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了,我还是有一点没有明白,
就是输出路径的时候我只在每一种状态上记录了前一种状态,最后回溯输出,但我还不确定这样做是对的。路过的大牛帮我想想,指点一下我哈。
原文地址:https://www.cnblogs.com/moonbay/p/2110546.html