HDU1074 Doing Homework

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074

分析:状压dp;看的dalao的题解。。。

用二进制表示,最大1<<n,对于他的二进制每一位分别表示第几个科目是否做了

 1 #include<iostream>
 2 #include<sstream>
 3 #include<cstdio>
 4 #include<cstdlib>
 5 #include<string>
 6 #include<cstring>
 7 #include<algorithm>
 8 #include<functional>
 9 #include<iomanip>
10 #include<numeric>
11 #include<cmath>
12 #include<queue>
13 #include<vector>
14 #include<set>
15 #include<cctype>
16 #define PI acos(-1.0)
17 const int INF = 0x3f3f3f3f;
18 const int NINF = -INF - 1;
19 const int maxn = (1 << 15) + 10;
20 typedef long long ll;
21 using namespace std;
22 int n;
23 int dp[maxn], tim[maxn], print[maxn];
24 struct node
25 {
26     char name[105];
27     int dead, cost;
28 }arr[20];
29 void output(int x)//递归打印,会从第一门开始打印
30 {
31     if (!x) return;
32     output(x - (1 << print[x]));//以第一次执行到这里为例,接下来x会从total-1(也就是完成所有作业的状态)转变为完成了n-1门的状态(去除了最后完成的一门)
33     printf("%s
", arr[print[x]].name);//print[x]里储存的是第几门
34 }
35 int main()
36 {
37     int T;
38     scanf("%d", &T);
39     while (T--)
40     {
41         scanf("%d", &n);
42         for (int i = 0; i < n; ++i)
43             scanf("%s %d %d", arr[i].name, &arr[i].dead, &arr[i].cost);
44         memset(tim, 0, sizeof(tim));
45         int total = 1 << n;
46         for (int i = 1; i < total; ++i)
47         {
48             dp[i] = INF;
49             for (int j = n - 1; j >= 0; --j)//j为i状态下最后完成的一门
50             {
51                 int tmp = 1 << j;//只完成了第j门的状态
52                 if (!(tmp & i)) continue;//如果i状态下第j门没有完成就跳出
53                 int score = tim[i - tmp] + arr[j].cost - arr[j].dead;//i-tmp为i下未完成j门的状态
54                 if (score < 0) score = 0;//得分不可能是负数
55                 if (dp[i] > dp[i - tmp] + score)//如果对于i状态,最后完成j门的解更优,那就更新
56                 {
57                     dp[i] = dp[i - tmp] + score;
58                     tim[i] = tim[i - tmp] + arr[j].cost;
59                     print[i] = j;//对于i,最后完成的是j
60                 }
61             }
62         }
63         printf("%d
", dp[total - 1]);//结果必然是全部做完了,即total-1,二进制全部为1
64         output(total - 1);打印
65     }
66     return 0;
67 }
原文地址:https://www.cnblogs.com/veasky/p/11298637.html