hdu 1074(Doing Homework)

hdu 1074(Doing Homework)
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include< string>
 5 #include<algorithm>
 6  using  namespace std;
 7  #define inf 0x7ffffff
 8  struct homework{
 9      char name[110];
10      int dl;
11      int ct;
12      int no; // 输出序列
13       int temp; // 临时标记
14  };
15 homework hw[20];
16  int dp[40000];
17  int n,cas,min_reduce;
18  int cmp(homework a,homework b){
19      return a.no<b.no;
20 }
21  void dfs( int steps, int score, int day, int now){
22      // 课程完成数、当前搜索深度的扣分值,当前消耗的天数,当前的状态
23       int i;
24      if(steps==n){
25          if(score<min_reduce){
26             min_reduce=score;
27              for(i=0;i<n;i++)
28                 hw[i].no=hw[i].temp;
29         }
30          return ;
31     }
32      if(dp[now]>score) // 此处的剪枝很关键 判断此课程是否之前已存在最优解
33          dp[now]=score;
34      else
35          return ;
36      for(i=0;i<n;i++){
37          if(hw[i].temp)
38              continue;
39         hw[i].temp=steps+1; // 记录顺序
40           int cost=0;
41          if(hw[i].ct+day>hw[i].dl) // 扣分
42              cost=hw[i].ct+day-hw[i].dl;
43         dfs(steps+1,score+cost,day+hw[i].ct,now+(1<<i)); // 下一课程
44          hw[i].temp=0; // 记忆化搜索
45      }
46 }
47  int main(){
48      // freopen("in.txt","r",stdin);
49       int i;
50     scanf("%d",&cas);
51      while (cas--){
52         scanf("%d",&n);
53          for(i=0;i<n;i++){
54             getchar();
55             scanf("%s %d %d",&hw[i].name,&hw[i].dl,&hw[i].ct);
56             hw[i].no=hw[i].temp=0;
57         }
58          for(i=0;i<40000;i++)
59             dp[i]=inf;
60          // 由截止日期与开销决定作业完成先后次序,如何判定优先级
61          min_reduce=inf;
62         dfs(0,0,0,0);
63         sort(hw,hw+n,cmp);
64         printf("%d\n",min_reduce);
65          for(i=0;i<n;i++)
66             printf("%s\n",hw[i].name);
67     }
68      return 0;
69 }
70 

你可能感兴趣的:(hdu 1074(Doing Homework))