zoukankan      html  css  js  c++  java
  • Doing Homework(hdu)1074

    Doing Homework

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 6967    Accepted Submission(s): 3043


    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
     
    思路:状压DP.
    一开始想全排列,往这思路上想,这样谁都知道会超时,因为n<15;那么共有pow(2,n)的状态,那么状压dp可解决.
    每个状态可由前面多个状态转移而来,所以取最小就是这个状态的最优解,局部最优,最后到整体最优。
    状态转移方程和解释具体看下面代码
      1 #include<stdio.h>
      2 #include<algorithm>
      3 #include<iostream>
      4 #include<string.h>
      5 #include<stdlib.h>
      6 #include<queue>
      7 #include<stack>
      8 #define sc(x) scanf("%I64d",&x)
      9 #define pr(x) printf("%I64d",x);
     10 #define prr(x) printf("%I64d
    ",x);
     11 #define prrr(x) printf(" %I64d",x);
     12 #define FOR(i,p,q) for(int i=p;i<=q;i++)
     13 int cmp(char *p,char *q);
     14 typedef struct pp
     15 {
     16     int x;
     17     int y;
     18     char a[200];
     19 } ss;
     20 ss ab[20];
     21 char bc[20][200];
     22 const int N=1e9;
     23 typedef struct qq
     24 {
     25     int time;
     26     int pre;
     27     int no;
     28     int cost;
     29 } kk;//结构体存这个状态的时间当前加入作业的编号,所罚的时间,和前一个状态
     30 kk dp[1<<15+1];
     31 using namespace std;
     32 int main(void)
     33 {
     34     int n,i,j,k,p,q;
     35     scanf("%d",&k);
     36     while(k--)
     37     {
     38         scanf("%d",&n);
     39         for(i=0; i<n; i++)
     40         {
     41             scanf("%s",ab[i].a);
     42             scanf("%d %d",&ab[i].x,&ab[i].y);
     43         }
     44         for(i=0; i<(1<<15)+1; i++)
     45         {
     46             dp[i].cost=N;
     47         }//初始化
     48         dp[0].cost=0;
     49         dp[0].pre=-1;
     50         dp[0].time=0;//开始的时间等状态
     51         for(i=1; i<(1<<n); i++)
     52         {
     53             for(j=0; j<n; j++)
     54             {
     55                 if(i&(1<<j))//当前这个状态含有第j个作业
     56                 {
     57                     if(ab[j].x<=dp[i^(1<<j)].time)//找不含j的前一个状态,并用前一个状态结束时间与第j个作业截至时间比较,然后分情况讨论下
     58                     {
     59                         int cc=dp[i^(1<<j)].time-ab[j].x;
     60                         if(dp[i].cost>dp[i^(1<<j)].cost+cc+ab[j].y)
     61                         {
     62                             dp[i].cost=dp[i^(1<<j)].cost+cc+ab[j].y;
     63                             dp[i].pre=i^(1<<j);
     64                             dp[i].no=j;
     65                             dp[i].time=dp[i^(1<<j)].time+ab[j].y;
     66                         }
     67                         else if(dp[i].cost==dp[i^(1<<j)].cost+cc+ab[j].y)
     68                         {
     69                             if(cmp(ab[j].a,ab[dp[i].no].a)>0)//按字典序排序,将最大的放最后,因为没个都是两两比较
     70                             {
     71                                 dp[i].cost=dp[i^(1<<j)].cost+cc+ab[j].y;
     72                                 dp[i].pre=i^(1<<j);
     73                                 dp[i].no=j;
     74                                 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
     75                             }
     76                         }
     77                     }
     78                     else
     79                     {
     80                         int uu=ab[j].y+dp[i^(1<<j)].time;
     81                         int cc=uu-ab[j].x;
     82                         if(cc<=0)
     83                         {
     84                             if(dp[i].cost>dp[i^(1<<j)].cost)
     85                             {
     86                                 dp[i].cost=dp[i^(1<<j)].cost;
     87                                 dp[i].pre=i^(1<<j);
     88                                 dp[i].no=j;
     89                                 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
     90                             }
     91                             else if(dp[i].cost==dp[i^(1<<j)].cost)
     92                             {
     93                                 if(cmp(ab[j].a,ab[dp[i].no].a)>0)
     94                                 {
     95                                     dp[i].cost=dp[i^(1<<j)].cost;
     96                                     dp[i].pre=i^(1<<j);
     97                                     dp[i].no=j;
     98                                     dp[i].time=dp[i^(1<<j)].time+ab[j].y;
     99                                 }
    100                             }
    101 
    102                         }
    103                         else
    104                         {
    105                             if(dp[i].cost>dp[i^(1<<j)].cost+cc)
    106                             {
    107                                 dp[i].cost=dp[i^(1<<j)].cost+cc;
    108                                 dp[i].pre=i^(1<<j);
    109                                 dp[i].no=j;
    110                                 dp[i].time=dp[i^(1<<j)].time+ab[j].y;
    111                             }
    112                             else if(dp[i].cost==dp[i^(1<<j)].cost+cc)
    113                             {
    114                                 if(cmp(ab[j].a,ab[dp[i].no].a)>0)
    115                                 {
    116                                     dp[i].cost=dp[i^(1<<j)].cost+cc;
    117                                     dp[i].pre=i^(1<<j);
    118                                     dp[i].no=j;
    119                                     dp[i].time=dp[i^(1<<j)].time+ab[j].y;
    120                                 }
    121                             }
    122 
    123                         }
    124 
    125                     }
    126                 }
    127             }
    128         }
    129       printf("%d
    ",dp[(1<<n)-1].cost);
    130         int pf=dp[(1<<n)-1].pre;
    131         int zk=0;
    132         while(zk<n-1)
    133         {
    134 
    135             strcpy(bc[zk],ab[dp[pf].no].a);
    136             zk++;
    137           pf=dp[pf].pre;
    138         }
    139         for(i=n-2;i>=0;i--)
    140         {
    141             printf("%s
    ",bc[i]);
    142         }printf("%s
    ",ab[dp[(1<<n)-1].no].a);
    143     }
    144 
    145 
    146 }
    147 int cmp(char *p,char *q)
    148 {
    149     return strcmp(p,q);
    150 }
    状压DP
    油!油!you@
  • 相关阅读:
    PCB 铺铜 转载
    VC++ 学习笔记3 获取编辑框字符串
    VC++ 学习笔记2 列表框添加字符串
    VC++组合框——学习笔记1(组合框选项的添加和无法显示下拉选项)
    微信蓝牙ble记录
    最近遇到的问题与分析还有可能的结果
    注入与以往的开发思路
    abp的权限与导航菜单的关系
    ionic入坑记记录
    abp相关
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5164815.html
Copyright © 2011-2022 走看看