hdu 1074 狀態壓縮

http://acm.hdu.edu.cn/showproblem.php?pid=1074php

咱們能夠判定狀態的終止態必定是n個數所有選完的狀況,那麼它的前一個狀態是什麼呢,必定是剔除任一門課程後的n種狀態。node

例如ios

dp[全選了]=min{(dp[除了math都作了]+math的超時天數),(dp[除了computer都作了]+computer的超時天數),(dp[除了english都作了]+english的超時天數)}那麼接下來的dp狀態依然如此。spa

好了,接下來,咱們該如何去思考了,這個題目共有2^15種可能狀況,對此咱們經過位運算方法下降它的維度。code

二進制的每一位表明一門課,它的組合能夠完成展現出全部的狀態。blog

最後咱們應該去思考一個問題,順序的問題,咱們知道,第一次取得時候,必定只有一個課程,若是咱們以string

1 int bit = 1<<n;
2 for(int i = 1;i<bit;i++)

可否確保某一個狀態的前一個都徹底包含,你能夠本身去檢驗,是徹底知足的.it

代碼:io

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int MAXN = (1<<15)+10;
 7 const int INF = 0x3f3f3f;
 8 struct node
 9 {
10     char str[105];
11     int d;//the deadtime
12     int c;//need spend time
13 };
14 node nd[20];
15 int dp[MAXN],pre[MAXN],t[MAXN];
16 void output(int x)
17 {
18     if(!x)
19         return ;
20     output(x-(1<<(pre[x]-1)));
21     printf("%s\n",nd[pre[x]].str);
22 }
23 int main()
24 {
25     int cas,n;
26     scanf("%d",&cas);
27     while(cas--)
28     {
29         memset(t,0,sizeof(t));
30         memset(pre,0,sizeof(pre));
31         //memset(dp,0,sizeof(dp));
32         scanf("%d",&n);
33         for(int i = 1;i<=n;i++)
34         {
35             scanf("%s%d%d",nd[i].str,&nd[i].d,&nd[i].c);
36         }
37        /* for(int i = 1;i<=n;i++)
38         {
39             printf("%s %d %d\n",nd[i].str,nd[i].d,nd[i].c);
40         }*/
41         int bit = 1<<n;
42         for(int i = 1;i<bit;i++)
43         {
44             dp[i] = INF;
45             for(int j = n;j>=1;j--)
46             {
47                 int temp = 1<<(j-1);
48                 if(!(temp&i))
49                     continue;
50                 else
51                 {
52                     int dist = (t[i-temp]+nd[j].c-nd[j].d);
53                     if(dist > 0)
54                     {
55                         if(dp[i]>(dp[i-temp]+dist))
56                         {
57                             t[i]=t[i-temp]+nd[j].c;
58                             dp[i]=dp[i-temp]+dist;
59                             pre[i] = j;
60                         }
61                     }
62                     else
63                     {
64                         if(dp[i]>dp[i-temp])
65                         {
66                             t[i]=t[i-temp]+nd[j].c;
67                             dp[i]=dp[i-temp];
68                             pre[i] =j;
69                         }
70                     }
71                 }
72             }
73         }
74         cout<<dp[bit-1]<<endl;
75         output(bit-1);
76     }
77     return 0;
78 }
相關文章
相關標籤/搜索