HDU 1074 Doing Homework(状压DP)

第一次写博客ORZ……

http://acm.split.hdu.edu.cn/showproblem.php?pid=1074

http://acm.hdu.edu.cn/showproblem.php?pid=1074

这两个总有一个是可以点开的……

题意比较清晰的啦。

做法的话暴力显然不合适,15!太大。

所以考虑状压DP……

代码参考了网上大神的。十分感谢。谢谢@键盘上的舞者

http://blog.csdn.net/libin56842/article/details/24316493

细节问题比较麻烦。在扣分相同的情况下要按字母输出课程名称。这个地方我卡了半天呢。

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <functional>
 6 
 7 using namespace std;
 8 
 9 #define REP(i,n)        for(int i(0); i <  (n); ++i)
10 #define rep(i,a,b)        for(int i(a); i <= (b); ++i)
11 #define dec(i,a,b)        for(int i(a); i >= (b); --i)
12 #define for_edge(i,x)        for(int i = H[x]; i; i = X[i])
13 
14 #define LL    long long
15 #define ULL    unsigned long long
16 #define MP    make_pair
17 #define PB    push_back
18 #define FI    first
19 #define SE    second
20 #define INF    1 << 26
21 
22 const int N    =    100000        +    10;
23 const int M    =    10000        +    10;
24 const int Q    =    1000        +    10;
25 const int A    =    15        +    1;
26 
27 struct node{
28     int time, score, pos, pre;
29 } dp[1 << A];
30 
31 int cost[A];
32 char name[A][Q];
33 int dead[Q];
34 int T;
35 int n;
36 
37 
38 void print(int k){
39     if (dp[k].pre) print(dp[k].pre);
40     puts(name[dp[k].pos]);
41 }    
42     
43 int main(){
44 #ifndef ONLINE_JUDGE
45     freopen("test.txt", "r", stdin);
46     freopen("test.out", "w", stdout);
47 #endif
48 
49     scanf("%d", &T);
50     REP(Case, T){
51         memset(dp, 0, sizeof dp);
52         scanf("%d", &n);
53         REP(i, n) scanf("%s%d%d", name[i], dead + i, cost + i);
54         int S = (1 << n) - 1;
55         rep(now, 1, S){
56             dp[now].score = INF;
57             bool flag = false;
58             REP(i, n) if (now & (1 << i)){
59                 int past = now ^ (1 << i);
60                 int st = dp[past].time + cost[i] - dead[i]; st = max(st, 0);
61                 if (st + dp[past].score < dp[now].score || (flag && st + dp[past].score == dp[now].score && strcmp(name[dp[now].pos], name[i]) < 0)){
62                     flag = true;
63                     dp[now].score = st + dp[past].score; dp[now].pos = i;
64                     dp[now].pre = past; dp[now].time = dp[past].time + cost[i];
65                 }
66             }
67         }
68         
69         printf("%d\n", dp[S].score);
70         print(S);
71         
72     }
73     
74     
75     
76     return 0;
77     
78 }
View Code

 

posted @ 2016-08-24 21:49  cxhscst2  阅读(187)  评论(0编辑  收藏  举报