UVA - 10817 Headmaster's Headache

Posted D O Time

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA - 10817 Headmaster's Headache相关的知识,希望对你有一定的参考价值。

题目大意:有一些老师,每一位都有自己的工资以及教授的课程。共s<=8个课程。其中的一些老师必须选择,问你保证每节课至少有一个老师的最少总工资。

题解:

首先很容易想到状态压缩,搞一个3进制的数,分别表示每一门课程的情况,一共38=6561。但是这样是不行的,相当于暴力啊!
一个套路:三进制转化为二进制*2。也就是搞一个216的数,1~8和9~16表示每门课程,这样就可以利用位运算了。
然后知道这个就很显然的,一个背包问题。要注意,这样转化为二进制之后,要定义一条规则,每次添加课程,优先1~8位,有了就再加到9~16位即可。
处理出所有强制选择的老师的授课状态S,令dp[S]=sum{c[]}。其他的全是INF。然后从All=(1<<(s*2)-1到S。当成01背包做即可。

 1 #include<queue>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #define RG register
 8 #define LL long long
 9 #define fre(a) freopen(a".in","r",stdin);//freopen(a".out","w",stdout);
10 using namespace std;
11 const int MAXN=1000;
12 int s,n,m,S,sum,All;
13 int c[MAXN],a[MAXN],dp[1<<16];
14 char ch;
15 int main()
16 {
17    while(scanf("%d%d%d",&s,&n,&m)!=EOF)
18       {
19          if(s==0)break;
20          All=(1<<(s*2))-1;
21          for(int i=1,flag,x;i<=n+m;i++)//鬼里鬼气的输入
22             {
23                a[i]=0;
24                scanf("%d",&c[i]);
25                flag=0;
26                while(1)
27                   {
28                      ch=getchar();
29                      while(ch<0||ch>9)
30                         {
31                            if(ch==\n||ch==\r) { flag=1; break; }
32                            ch=getchar();
33                         }
34                      if(flag)break;
35                      x=0;
36                      while(0<=ch&&ch<=9)x=x*10+(ch-0),ch=getchar();
37                      a[i]|=(1<<(x-1));
38                      if(ch==\n||ch==\r)break;
39                   }
40             }
41          S=sum=0;
42          for(int i=1;i<=n;i++)//按照规则,优先填后面的
43             {
44                sum+=c[i];
45                int p=S&a[i];
46                S|=(p<<s);
47                S|=a[i];
48             }
49          memset(dp,0x3f3f3f3f,sizeof dp);
50          dp[S]=sum;
51          for(int i=n+1;i<=n+m;i++)
52             {
53                for(int j=All;j>=S;j--)//按照规则,优先填后面的
54                   {
55                      int p=a[i]&j;
56                      p=a[i]|(p<<s);
57                      dp[j|p]=min(dp[j|p],dp[j]+c[i]);
58                   }
59             }
60          printf("%d\n",dp[All]);
61       }
62    return 0;
63 }

以上是关于UVA - 10817 Headmaster's Headache的主要内容,如果未能解决你的问题,请参考以下文章

Headmaster's Headache UVa10817DP(缺)

UVA - 10817 Headmaster's Headache (状压dp+记忆化搜索)

(状压dp)uva 10817 Headmaster's Headache

UVA - 10817 Headmaster's Headache (状压类背包dp+三进制编码)

UVa 10817 校长的烦恼

c_cpp UVa 10817 - 校长的头痛