Doing Homework 状态压缩DP

                        Doing Homework

题目抽象:给出n个task的name,deadline,need。  每个任务的罚时penalty=finish-deadline;   task不可以同时做。问按怎样的顺序做使得penalty最小。同时输出顺序。如果有多个满足条件的顺序,按字典序输出。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <string>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <list>
13 #include <iomanip>
14 #include <cstdlib>
15 #include <sstream>
16 using namespace std;
17 typedef long long LL;
18 const int INF=0x5fffffff;
19 const double EXP=1e-6;
20 const int MS=16;
21
22 struct task
23 {
24       char name[105];
25       int deadline,need;
26 }tasks[MS];
27
28 struct node
29 {
30       int time,penalty;   //  到达这个状态的时间,和罚时
31       int cur,pre;          //   状态s的物理变化过程
32 }nodes[1<<MS];
33
34 int n,m;
35
36 void solve()
37 {
38       for(int i=1;i<=m;i++)        //  note   i==1
39             nodes[i].penalty=INF;
40       nodes[0].time=0;
41       for(int i=0;i<=m;i++)
42       {
43             for(int j=0;j<n;j++)
44                   if(!((i>>j)&1))
45                   {
46                         int next=i|(1<<j);
47                         int finish=nodes[i].time+tasks[j].need;
48                         int penalty=max(0,finish-tasks[j].deadline);
49                         penalty+=nodes[i].penalty;
50                         if(penalty<nodes[next].penalty)
51                         {
52                               nodes[next].time=finish;
53                               nodes[next].penalty=penalty;
54                               nodes[next].cur=j;
55                               nodes[next].pre=i;
56                         }
57                   }
58       }
59 }
60
61 void output(int x)
62 {
63       if(x==0)
64             return ;
65        output(nodes[x].pre);
66        printf("%s\n",tasks[nodes[x].cur].name);
67 }
68
69 int main()
70 {
71       int T;
72       scanf("%d",&T);
73       while(T--)
74       {
75             scanf("%d",&n);
76             for(int i=0;i<n;i++)
77                   scanf("%s%d%d",tasks[i].name,&tasks[i].deadline,&tasks[i].need);
78             m=(1<<n)-1;
79             solve();
80             printf("%d\n",nodes[m].penalty);
81             output(m);
82       }
83       return 0;
84 }
时间: 2024-10-06 20:23:46

Doing Homework 状态压缩DP的相关文章

HDU1074 Doing Homework 状态压缩dp

题目大意: 根据完成任务的截止时间,超时一天罚1分,求完成所有任务后的最小罚时 这里n最大为15,可以利用状态压缩来解决问题 1 /* 2 首先要明白的一点是状态1/0分别表示这件事做了还是没做 3 而1/0的位置表示这是哪一件事 4 比如说 5 可以表示为101,那么表示第一个和第三个任务已经完成 5 而dp[5]表示第一个和第三个任务完成所花费的最短时间 6 而状态5(101)是从状态1(001)或者状态4(100)转移过来的 7 也就是说我们总是可以通过一个较小的状态不断递推一个较大状态的

HDU 1074 Doing Homework(状态压缩 + DP)

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

HDU 1074 Doing Homework(状态压缩DP)

题意:有n门课,每门课有截止时间和完成所需的时间,如果超过规定时间完成,每超过一天就会扣1分,问怎样安排做作业的顺序才能使得所扣的分最小 思路:二进制表示. 1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<set> 7 #include<map> 8

状态压缩DP,附上例题(HDU - 1074 Doing Homework )

状态压缩DP:本生有很多状态,然后压缩成一种状态. 很多时候都会使用位运算 Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 10077    Accepted Submission(s): 4832 Problem Description Ignatius has just come back school

HDU1074(状态压缩DP)

Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7070    Accepted Submission(s): 3104 Problem Description Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lo

HDU_1074_Doing Homework_状态压缩dp

链接: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): 7543    Accepted Submission(s): 3375 Problem Description Ignatius has just come b

状态压缩dp问题

问题: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 o

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

HDU1565(状态压缩dp)

方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8170    Accepted Submission(s): 3095 Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数