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 #include<vector>
  9 #include<cstring>
 10 #include<stack>
 11 #include<cmath>
 12 #include<queue>
 13 #include <bits/stdc++.h>
 14 using namespace std;
 15 #define INF 0x3f3f3f3f
 16 #define ll long long
 17 #define clc(a,b) memset(a,b,sizeof(a))
 18 const int MAXN=1<<16;
 19 struct node
 20 {
 21     int cost;
 22     int pre;
 23     int reduced;
 24 } dp[MAXN];
 25 bool visited[MAXN];
 26 struct course
 27 {
 28     int deadtime;
 29     int cost;
 30     char name[201];
 31 } course[16];
 32 void output(int status)
 33 {
 34     int curjob=dp[status].pre^status;
 35     int curid=0;
 36     curjob>>=1;
 37     while(curjob)
 38     {
 39         curid++;
 40         curjob>>=1;
 41     }
 42     if(dp[status].pre!=0)
 43     {
 44         output(dp[status].pre);
 45     }
 46     printf("%s\n",course[curid].name);
 47 }
 48 int main()
 49 {
 50    // freopen("in.txt","r",stdin);
 51     int T,n;
 52     int i,j;
 53     scanf("%d",&T);
 54     while(T--)
 55     {
 56         scanf("%d",&n);
 57         int upper=1<<n;
 58         int dayupper=0;
 59         for(i=0; i<n; i++)
 60         {
 61             scanf("%s%d%d",&course[i].name,&course[i].deadtime,&course[i].cost);
 62             dayupper+=course[i].cost;
 63         }
 64         memset(visited,false,sizeof(visited));
 65         dp[0].cost=0;
 66         dp[0].pre=-1;
 67         dp[0].reduced=0;
 68         visited[0]=true;
 69         int work;
 70         int tupper=upper-1;
 71         for(j=0; j<tupper; j++)
 72         {
 73             for(work=0; work<n; work++)
 74             {
 75                 int cur=1<<work;
 76                 if((cur&j)==0)
 77                 {
 78                     int curtemp=cur|j;
 79                     int day=dp[j].cost+course[work].cost;
 80                     dp[curtemp].cost=day;
 81                     int reduce=day-course[work].deadtime;
 82                     if(reduce<0)reduce=0;
 83                     reduce+=dp[j].reduced;
 84                     if(visited[curtemp])
 85                     {
 86                         if(reduce<dp[curtemp].reduced)
 87                         {
 88                             dp[curtemp].reduced=reduce;
 89                             dp[curtemp].pre=j;
 90                         }
 91                     }
 92                     else
 93                     {
 94                         visited[curtemp]=true;
 95                         dp[curtemp].reduced=reduce;
 96                         dp[curtemp].pre=j;
 97                     }
 98                 }
 99             }
100         }
101         printf("%d\n",dp[tupper].reduced);
102         output(tupper);
103     }
104 }
View Code

 

posted @ 2016-01-30 16:00  yyblues  阅读(174)  评论(0编辑  收藏  举报