hdu 1074 Doing Homework

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

状压dp不是很懂,看着别人的代码写的,很长时间才看懂。 dp[i]记录(1<<n)-1个状态第i状态的最小结果。用pre数组记录每一个状态的前驱。

用dfs输出路径。

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #define maxn 16
 5 using namespace std;
 6 const int inf=1<<29;
 7 
 8 int dp[1<<16];
 9 int t,n;
10 int pre[1<<16];
11 struct node
12 {
13     char name[110];
14     int d;
15     int c;
16 }p[maxn*10];
17 
18 void dfs(int w)
19 {
20     if(w==0) return ;
21     int pos=0;
22     for(int i=0; i<n; i++)
23     {
24         if((w&(1<<i))!=0&&(pre[w]&(1<<i))==0)
25         {
26             pos=i;
27             break;
28         }
29     }
30     dfs(pre[w]);
31     printf("%s
",p[pos].name);
32 }
33 
34 int main()
35 {
36     scanf("%d",&t);
37     while(t--)
38     {
39         scanf("%d",&n);
40         for(int i=0; i<n; i++)
41         {
42             scanf("%s%d%d",p[i].name,&p[i].d,&p[i].c);
43         }
44         for(int i=0; i<(1<<n); i++)
45         {
46             dp[i]=inf;
47         }
48         dp[0]=0;
49         for(int i=0; i<(1<<n); i++)
50         {
51             for(int j=0; j<n; j++)
52             {
53                 if(i&(1<<j)) continue;
54                 int sum=0;
55                 for(int k=0; k<n; k++)
56                 {
57                     if(i&(1<<k)) sum+=p[k].c;
58                 }
59                 sum+=p[j].c;
60                 if(sum>p[j].d) sum-=p[j].d;
61                 else sum=0;
62                 if(dp[i|(1<<j)]>dp[i]+sum)
63                 {
64                     dp[i|(1<<j)]=dp[i]+sum;
65                     pre[i|(1<<j)]=i;
66                 }
67             }
68         }
69         printf("%d
",dp[(1<<n)-1]);
70         dfs((1<<n)-1);
71     }
72     return 0;
73 }
View Code
原文地址:https://www.cnblogs.com/fanminghui/p/4025249.html