HDU1074 Doing Homework
Posted veasky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n", 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\n", dp[total - 1]);//结果必然是全部做完了,即total-1,二进制全部为1 64 output(total - 1);打印 65 66 return 0; 67
以上是关于HDU1074 Doing Homework的主要内容,如果未能解决你的问题,请参考以下文章