zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    用Azure VM + Azure Database for MySQL搭建Web服务
    Azure镜像的跨区域复制—Shared Image Gallery(共享映像库)初探
    Azure上几种常见的VM复制操作
    Exchange 2016与国内版O365混合部署(6):混合后的操作和验证
    Exchange 2016与国内版O365混合部署(5):运行AAD Connect及混合部署向导
    Exchange 2016与国内版O365混合部署(4):配置Exchange 公网证书
    Exchange 2016与国内版O365混合部署(3):安装Exchange2016并配置邮件的外网收发
    Exchange 2016与国内版O365混合部署(2):搭建域环境
    Exchange 2016与国内版O365混合部署(1):过程总览
    Cross-Tanant 步骤
  • 原文地址:https://www.cnblogs.com/yaling/p/3232219.html
Copyright © 2011-2022 走看看