http://acm.hdu.edu.cn/showproblem.php?pid=1074
2 3 Computer 3 3 English 20 1 Math 3 2 3 Computer 3 3 English 6 3 Math 6 3
2 Computer Math English 3 Computer English Math
最后DFS回溯输出路径
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <queue> #include <stack> #include <algorithm> using namespace std; #define N 20 #define INF 0x3f3f3f3f #define MOD 2009 #define met(a, b) memset (a, b, sizeof(a)) typedef long long LL; struct node { char str[N]; int deadline;///当前这门课程的截止日期 int cost;///学完当前这门课程所要花费的时间 }stu[N]; struct node1 { int time;///学完当前这门课程花费的最少时间 int score;///学完当前这门课程扣除的最少分数 int now;///当前学的课程 int pre;///上一门学的课程 }dp[1<<16]; void Search_path (int n) { if (!n) return; Search_path (dp[n].pre); printf ("%s\n", stu[dp[n].now].str); return; } int main () { int t, n; scanf ("%d", &t); while (t--) { met (dp, 0); met (stu, 0); scanf ("%d", &n); for (int i=0; i<n; i++) scanf ("%s%d%d", stu[i].str, &stu[i].deadline, &stu[i].cost); int Lim = (1<<n)-1; for (int i=1; i<=Lim; i++) { dp[i].score =INF; for (int j=n-1; j>=0; j--) { if (i & (1<<j)) { int x = i - (1<<j); int Score = dp[x].time + stu[j].cost - stu[j].deadline; if (Score < 0) Score = 0; if (Score + dp[x].score < dp[i].score) { dp[i].score = Score + dp[x].score; dp[i].time = dp[x].time + stu[j].cost; dp[i].pre = x; dp[i].now = j; } } } } printf ("%d\n", dp[Lim].score); Search_path (Lim); } return 0; }
记忆化搜索
#include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <queue> #include <stack> #include <algorithm> using namespace std; #define N 20 #define INF 0x3f3f3f3f #define MOD 2009 #define met(a, b) memset (a, b, sizeof(a)) typedef long long LL; struct node { char str[N]; int deadline;///当前这门课程的截止日期 int cost;///学完当前这门课程所要花费的时间 }stu[N]; struct node1 { int time;///学完当前这门课程花费的最少时间 int score;///学完当前这门课程扣除的最少分数 }dp[1<<16]; int n; void Solve (node1 &A, node1 B, node C) { int Time = B.time + C.cost; int Score = B.score + abs(min(C.deadline-Time, 0)); if (A.score > Score|| (A.score==Score && A.time<Time)) { A.score = Score; A.time = Time; } } node1 DFS (int Sta) { if (dp[Sta].score != -1) return dp[Sta]; dp[Sta].score = INF; for (int i=0; i<n; i++) { if (Sta & (1<<i)) Solve (dp[Sta], DFS (Sta-(1<<i)), stu[i]); } return dp[Sta]; } bool OK (node1 A, node1 B, node C) { int Time = B.time + C.cost; int Score = B.score + abs (min (C.deadline-Time, 0)); if (A.score == Score && A.time == Time) return true; return false; } void Search_path (int Sta) { if (!Sta) return; for (int i=n-1; i>=0; i--) { if (Sta & (1<<i) && OK (dp[Sta], dp[Sta-(1<<i)], stu[i])) { Search_path(Sta-(1<<i)); puts (stu[i].str); break; } } } int main () { int t; scanf ("%d", &t); while (t--) { scanf ("%d", &n); for (int i=0; i<n; i++) scanf ("%s%d%d", stu[i].str, &stu[i].deadline, &stu[i].cost); met (dp, -1); dp[0].score = dp[0].time = 0; node1 A = DFS ((1<<n)-1); printf ("%d\n", A.score); Search_path((1<<n)-1); } return 0; }