HDU Doing Homework

据说是状态压缩DP,我用bfs()做了,其实思想是一样的,下面是我的代码:仅供参考。

 

 1 //此题可用二进制表示所有的状态,一个进制数的每一位对应一种作业,如果是1表示做这种作业,
 2 //但是还有个先做哪种作业的顺序,此时可以先让每一位都为1为第一种状态,到下一种状态时,
 3 //可以把一个0变为1,表示下来做这种作业,如果遇到过这种状态,但先后顺序不一样,则保留最优解,
 4 //可以举个例子,比如有三种作业,那么最初的状态为{(001) (010) (100)} 分别表示先做标记为1的作业,
 5 //则下一个状态便为: (001) -> { (011) , (101) }  (010) -> {(110) , (011)}; (100) ->{ (101), (110) }
 6 //有相同的状态则会记录最优的一个状态,超时最少的,下来就到最后一种状态(111), (111)状态先取最优的即为结果
 7 #include <iostream>
 8 #include <cstring>
 9 #include <queue>
10 #include <string>
11 using namespace std;
12 const int N = 1<<16;
13 //visit标记状态有没有访问过 
14 //a记录超过的最短时间  b记录写作业一共花费的时间  
15 //pre记录作业的先后顺序,回溯输出结果
16 bool visit[N]; int a[N], b[N], pre[N];
17 struct Node{
18     string sub;  //科目
19     int ed, t;//结束时间、持续时间
20 }Sub[16];
21 
22 void f(int p){//回溯输出结果
23     if(pre[p] == -1return;
24     else{
25         int t = pre[p];  t = p ^ (1<<t);
26         f(t);
27         cout<<Sub[pre[p]].sub<<endl;
28     }
29 }
30 int bfs(int n){
31     memset(visit, falsesizeof(visit));
32     memset(a, 0sizeof(a));
33     memset(pre, 0sizeof(pre));
34     queue<int> q;
35     int i, j, t1, t2;
36     pre[0] = -1;
37     for(i = 0; i < n; ++i){  //初始化每种作业为初状态
38         j = 1 << i;
39         q.push(j); pre[j] = i; b[j] = Sub[i].t;
40         if(Sub[i].t <= Sub[i].ed) a[j] = 0;
41         else a[j] = Sub[i].t - Sub[i].ed;
42         visit[j] = true;
43     }
44     while(!q.empty()){
45         t1 = q.front(); q.pop();
46         for(i = 0; i < n; ++i){
47             j = 1 << i; t2 = t1 & j; //判断此作业是否做过,做过为1,未做过为0
48             if( !t2 ){
49                 t2 = t1 | j;//下一种状态
50                 if(!visit[t2]){ //没有访问过此状态
51                     visit[t2] = true;  b[t2] = b[t1] + Sub[i].t;
52                     if(b[t2] > Sub[i].ed) a[t2] = a[t1] + b[t2] - Sub[i].ed;
53                     else a[t2] = a[t1];
54                     q.push(t2);  pre[t2] = i;
55                 }else{
56                     int s1 = b[t1] + Sub[i].t;
57                     if(s1 > Sub[i].ed) s1 = a[t1] + s1 - Sub[i].ed;
58                     else s1 = a[t1];
59                     if(a[t2] > s1){
60                         a[t2] = s1; b[t2] = b[t1] + Sub[i].t;
61                         q.push(t2); pre[t2] = i;
62                     }
63                 }
64             }
65         }
66     } cout<<a[t1]<<endl;  f(t1);
67 }
68 
69 int main(){
70     int t, N, i;
71     cin>>t;
72     while(t--){
73         cin>>N;
74         for(i = 0; i < N; ++i)
75         cin>>Sub[i].sub>>Sub[i].ed>>Sub[i].t;
76         bfs(N);
77     }
78     return 0;
79 }
View Code

 

posted @ 2013-08-02 11:34  YaLing  阅读(287)  评论(0编辑  收藏  举报