hdu 1074 Doing Homework (状压 + 记录路径)
来源:互联网 发布:如何看待人工智能 编辑:程序博客网 时间:2024/06/02 02:07
http://acm.hdu.edu.cn/showproblem.php?pid=1074
Doing Homework
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7316 Accepted Submission(s): 3240
Problem Description
Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Every teacher gives him a deadline of handing in the homework. If Ignatius hands in the homework after the deadline, the teacher will reduce his score of the final test, 1 day for 1 point. And as you know, doing homework always takes a long time. So Ignatius wants you to help him to arrange the order of doing homework to minimize the reduced score.
Input
The input contains several test cases. The first line of the input is a single integer T which is the number of test cases. T test cases follow.
Each test case start with a positive integer N(1<=N<=15) which indicate the number of homework. Then N lines follow. Each line contains a string S(the subject's name, each string will at most has 100 characters) and two integers D(the deadline of the subject), C(how many days will it take Ignatius to finish this subject's homework).
Note: All the subject names are given in the alphabet increasing order. So you may process the problem much easier.
Each test case start with a positive integer N(1<=N<=15) which indicate the number of homework. Then N lines follow. Each line contains a string S(the subject's name, each string will at most has 100 characters) and two integers D(the deadline of the subject), C(how many days will it take Ignatius to finish this subject's homework).
Note: All the subject names are given in the alphabet increasing order. So you may process the problem much easier.
Output
For each test case, you should output the smallest total reduced score, then give out the order of the subjects, one subject in a line. If there are more than one orders, you should output the alphabet smallest one.
Sample Input
23Computer 3 3English 20 1Math 3 23Computer 3 3English 6 3Math 6 3
Sample Output
2ComputerMathEnglish3ComputerEnglishMath
题目大意:
有n门课程,每门课程有个作业。这个作业有个最晚上交时间和完成这门课需要的时间。假如没有按照规定时间完成,每晚一天减少一分。
思路:枚举(1<<n)-1种状态,一共n门课程,对每种课程的状态,判断该课程(1<<i)能否右(1--(1<<n))种状态中的一个状态得到,然后dp记录学习了当前课程所花费的时间,和上一门课程的是哪门有n门课程,每门课程有个作业。这个作业有个最晚上交时间和完成这门课需要的时间。假如没有按照规定时间完成,每晚一天减少一分。
最后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;}
1 0
- hdu 1074 Doing Homework (状压 + 记录路径)
- HDU 1074 Doing Homework(状压DP+记录路径)
- HDU 1074 Doing Homework(状压dp+记录路径)
- HDU 1074 Doing Homework (状压DP + 路径记录)
- HDU 1074 Doing Homework (dp+状态压缩+路径记录)
- HDU 1074 Doing Homework(状压DP输出路径)
- HDU 1074 Doing Homework(状压DP+储存路径)
- hdu 1074 Doing Homework (状压dp)
- HDU 1074 Doing Homework(状压DP)
- HDU 1074-Doing Homework(状压DP)
- HDU 1074 Doing Homework(状压dp)
- HDU 1074 Doing Homework(状压DP)
- HDU 1074 Doing Homework(状压DP)
- hdu 1074 Doing Homework(状压DP)
- HDU 1074 Doing Homework(状压DP)
- hdu-1074 Doing Homework (状压dp)
- Hdu 1074Doing Homework(状压DP)
- 【状压DP+输出路径】HDU-1074 Doing Homework
- 重建二叉树
- java学习笔记(五)
- YD 督促训练 判断这年五一几天假期
- MongoDB用户权限设置
- jQuery实现图片轮播特性。使用animate函数
- hdu 1074 Doing Homework (状压 + 记录路径)
- android设置 默认wifi
- 9. Smarty3:模版继承
- Linux: xclip,pbcopy,xsel用法 terminal 复制粘帖 (mac , ubuntu)
- BZOJ 2327: [HNOI2011]勾股定理
- java虚拟机HotSpot中的垃圾收集器
- CSU 1719(智障选手的DFS)
- Struts2环境搭建
- s1:VB之摆出15个数