uva10817 Headmaster's Headache

来源:互联网 发布:学生管理系统java界面 编辑:程序博客网 时间:2024/06/05 23:42

The headmaster of Spring Field School is consider- ing employing
some new teachers for certain subjects. There are a number of teach-
ers applying for the posts. Each teacher is able to teach one or more
subjects. The headmaster wants to select applicants so that each sub-
ject is taught by at least two teachers, and the overall cost is
minimized. Input The input consists of several test cases. The format
of each of them is explained below: The rst line contains three
positive integers S , M and N . S (  8) is the number of subjects, M
(  20) is the number of serving teachers, and N (  100) is the
number of applicants. Each of the following M lines describes a
serving teacher. It rst gives the cost of employing him/her (10000 
C  50000), followed by a list of subjects that he/she can teach. The
subjects are numbered from 1 to S . You must keep on employing all of
them. After that there are N lines, giving the details of the
applicants in the same format. Input is terminated by a null case
where S
= 0. This case should not be processed. Output For each test case, give the minimum cost to employ the teachers under the constraints.

状压dp,记录下来现在有两个以上人教、一个人教的集合,然后枚举当前这个人雇佣或者不雇佣。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int oo=0x3f3f3f3f;int dp[130][1<<10][1<<10],a[130],c[130],n,m,s;#define DP dp[p][s2][s1]bool read(int &x){    x=0;    char c=getchar();    while (c<'0'||c>'9') c=getchar();    while (c>='0'&&c<='9')    {        x=x*10+c-'0';        c=getchar();    }    return c==' ';}int dfs(int p,int s2,int s1,int s0){    if (DP>=0) return DP;    if (p==m+n) return s2==(1<<s)-1?0:oo;    if (p>=m) DP=dfs(p+1,s2,s1,s0);    else DP=oo;    int x=s1&a[p],y=s0&a[p],ss2,ss1,ss0;    ss2=s2+x;    ss1=s1-x+y;    ss0=s0-y;    DP=min(DP,c[p]+dfs(p+1,ss2,ss1,ss0));    return DP;}int main(){    int i,x;    bool flag;    while (1)    {        read(s);        read(m);        read(n);        if (s==0) return 0;        memset(a,0,sizeof(a));        for (i=0;i<m+n;i++)        {            read(c[i]);            while (1)            {                flag=read(x);                a[i]|=1<<(x-1);                if (!flag) break;            }        }        memset(dp,0xff,sizeof(dp));        printf("%d\n",dfs(0,0,0,(1<<s)-1));    }}
0 0
原创粉丝点击