HDU 1074 Doing Homework //超详细解释
2014-08-13 15:57
337 查看
Doing Homework
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5187 Accepted Submission(s): 2155
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.
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
2 3 Computer 3 3 English 20 1 Math 3 2 3 Computer 3 3 English 6 3 Math 6 3
Sample Output
2 Computer Math English 3 Computer English Math Hint In the second test case, both Computer->English->Math and Computer->Math->English leads to reduce 3 points, but the word "English" appears earlier than the word "Math", so we choose the first order. That is so-called alphabet order.
Author
Ignatius.L
#include <stdio.h> #include <string.h> #define M 1<<16 struct node { char name[200]; int deadtime; //规定时间 int needtime; //需要时间 } course[20]; struct node1 { int reduce; //扣除分数 int cost; //总共需要的时间 int pre; //上一状态 } dp[M]; bool visit[M]; //记录状态 void output(int n); int main() { int t, n; int i, j; scanf("%d", &t); while(t--) { scanf("%d", &n); for(i=0; i<n; i++) scanf("%s%d%d", course[i].name, &course[i].deadtime, &course[i].needtime); memset(visit, false, sizeof(visit));//初始化,dp[0]代表完成0项作业 dp[0].cost = dp[0].reduce = 0; dp[0].pre = -1; visit[0] = true; int all = (1<<n)-1; for(i=0; i<all; i++) //访问所以状态,all对应的二进制是n个1 { for(j=0; j<n; j++) { int num = 1<<j; if((i&num) == 0) //当这个作业没有被完成时 { int now = num|i; //现在对应的状态 int cost = dp[i].cost + course[j].needtime; //当前状态需要的时间 int reduce = cost - course[j].deadtime; //当前状态扣除的分数 if(reduce < 0)reduce = 0; //扣除的分数不能为负 reduce += dp[i].reduce; //当前状态扣除的分数 dp[now].cost = cost; if(visit[now]==true) //当前状态没有被访问 { if(dp[now].reduce > reduce)//如果此时状态扣除的分数 比 原来扣除的分数少 更新 { dp[now].reduce = reduce; dp[now].pre = i; } else if(dp[now].reduce == reduce) //当扣除分数相同时,选字典序小的 { if(dp[now].pre > i) dp[now].pre = i; } } else //没有被访问过 { visit[now] = true; dp[now].reduce = reduce; dp[now].pre = i; } } } } printf("%d\n", dp[all].reduce); output(all); } return 0; } void output(int n)//递归输出名字 { int last = n^dp .pre; //n与dp .pre对应的二进制位只有一位是不同的 int num=0; last>>=1; //因为存course时是从0开始存的 while(last) { last>>=1; num++; //num表示1所在的位置,既是对应的第几项作业 } if(dp .pre != 0) output(dp .pre); printf("%s\n", course[num].name); }
相关文章推荐
- hdu1113 Word Amalgamation(详细解释--map和string的运用)
- HDU - 1024 Max Sum Plus Plus(最大M段连续子段和,详细解释)
- HDU2665 主席树原理解决静态区间第K大值问题总结 有详细图解和代码解释
- HDU-3713---Double Maze (bfs) 详细解释
- ipc$详细解释大全
- usertype的详细解释和使用实例
- 转贴:关于session的详细解释
- 弹出消息的bat代码(msg命令详细解释)
- 关于session的详细解释
- 究竟为什么内网不能用外网地址访问内部服务器。通俗详细的解释
- Emerge详细解释
- [补充]C++存储修饰符--生存空间详细解释
- 关于session的详细解释
- asp.net HttpHand和HttpModule的详细解释,包括Asp.Net对Http请求的处理流程。
- 转贴ipc$详细解释大全
- 内部服务器错误,HTTP 500的一个比较详细的解释(转帖)
- .Net 文件名后缀的详细解释
- 利用textbox自动生成一个表格 附详细解释
- 关于session的详细解释
- 带详细解释的冲击波原代码