【算法系列学习】状压dp [kuangbin带你飞]专题十二 基础DP1 D - Doing Homework

https://vjudge.net/contest/68966#problem/D

http://blog.csdn.net/u010489389/article/details/19218795

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<string>
  5 #include<algorithm>
  6 #include<cmath>
  7 #include<queue>
  8 #define INF 0x3f3f3f3f
  9 using namespace std;
 10 const int maxn=105;
 11 int n;
 12 struct hmwk
 13 {
 14     char ch[maxn];
 15     int d;
 16     int c;
 17 }p[16];
 18 
 19 struct DP
 20 {
 21     int time;
 22     int reduced;
 23     int fa;
 24 }dp[(1<<15)];
 25 
 26 char s[16][101];
 27 
 28 void Init()
 29 {
 30     for(int i=0;i<(1<<15);i++)
 31     {
 32         dp[i].fa=-1;
 33         dp[i].time=0;
 34         dp[i].reduced=INF;    
 35     }    
 36     dp[0].reduced=0;
 37     
 38 }
 39 //按字典序增序输出 
 40 bool cmp(const hmwk&x,const hmwk& y)
 41 {
 42     return strcmp(x.ch,y.ch)<=0;
 43 }
 44 //递归输出,x为当前,fa为前一个 
 45 void Print(int x,int fa)
 46 {
 47     int flag;
 48     if(x==0)
 49     {
 50         for(int i=0;i<n;i++)
 51         {
 52             if(fa&(1<<i))
 53             {
 54                 flag=i;    
 55                 break;
 56             }
 57         }
 58         printf("%s\n",p[flag].ch);
 59         return;
 60     }
 61     Print(dp[x].fa,x);
 62     for(int i=0;i<n;i++)
 63     {
 64         if((x&(1<<i))!=(fa&(1<<i)))
 65         {
 66             flag=i;
 67             break;
 68         }
 69     }
 70     if(x==0)
 71     {
 72         printf("%s\n",p[flag].ch);
 73     }    
 74     else
 75     {
 76         printf("%s\n",p[flag].ch);
 77     }
 78 }
 79 
 80 int main()
 81 {
 82     int T;
 83     scanf("%d",&T);
 84     while(T--)
 85     {
 86         
 87         scanf("%d",&n);
 88         for(int i=0;i<n;i++)
 89         {
 90             scanf("%s%d%d",p[i].ch,&p[i].d,&p[i].c);            
 91         }
 92         sort(p,p+n,cmp);
 93         Init();
 94         //每个i代表一个状态,i的每一位代表一个科目 
 95         for(int i=0;i<(1<<n);i++)
 96         {
 97             for(int k=0;k<n;k++)
 98             {
 99                 //如果是1跳过 
100                 if(i&(1<<k))
101                 {
102                     continue;
103                 }
104                 //now为转移后的状态 
105                 int now=i+(1<<k);
106                 dp[now].time=dp[i].time+p[k].c;
107                 //dp[now].time-p[k].d<0说明没有延期,就是0 
108                 if(dp[i].reduced+max(0,dp[now].time-p[k].d)<dp[now].reduced)
109                 {
110                     dp[now].reduced=dp[i].reduced+max(0,dp[now].time-p[k].d);
111                     dp[now].fa=i;    
112                 } 
113             }
114         }
115         //最终结果就是111111(n个1),对应的数就是(1<<n)-1 
116         printf("%d\n",dp[(1<<n)-1].reduced);
117         Print(dp[(1<<n)-1].fa,(1<<n)-1);
118     }
119     return 0;
120  } 
View Code

 

posted @ 2017-04-02 22:33  shulin15  阅读(343)  评论(0编辑  收藏  举报