UVA 10817 Headmaster's Headache - 状压dp

来源:互联网 发布:源码天下yuanmatx 编辑:程序博客网 时间:2024/05/16 10:30

题目描述

题目大意:

某校有m个在职教师和n个求职者,需讲授s个课程
(1<=s<=8,1<=m<=20,1<=n<=100 )。
已知每人的工资c(10000<=c<=50000)和能教的课程集合,要求支付最少的工资使得每门课都至少有两名教师能教。在职教师不能辞退。

(参考网上题解)

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define MAXS 8#define MAXM 20#define MAXN 100#define INF 2000000000#define MAXST 256int n,m,a[MAXN+MAXM+10],cnt[MAXS+10],st1,st2,sum,cost[MAXN+MAXM+10],s,S;int dp[MAXST+10][MAXST+10];void read(){    char c;    st1=st2=0,sum=0;    memset(cnt,0,sizeof cnt);    memset(a,0,sizeof a);    for(int i=1;i<=n+m;i++){        scanf("%d",&cost[i]);        while(c=getchar(),c!='\n'){            if(c>='0'&&c<='9'){                a[i]|=(1<<(c-'0'-1));                if(i<=m)                    cnt[c-'0']++;            }        }        if(i<=m){            sum+=cost[i];            st1|=a[i];        }    }    for(int i=1;i<=s;i++)        if(cnt[i]>=2)            st2|=(1<<(i-1));    S=(1<<s)-1;}void DP(){    for(int i=S;i>=0;i--)        for(int j=S;j>=0;j--)            dp[i][j]=INF; //dp[至少有一个人教][至少有两个人教]    dp[st1][st2]=sum;    for(int i=m+1;i<=n+m;i++){        for(int j=S;j>=0;j--)            for(int k=S,s1,s2;k>=0;k--){                if(dp[j][k]==INF)                    continue;                s1=j|a[i];                s2=(j&a[i])|k;                dp[s1][s2]=min(dp[s1][s2],dp[j][k]+cost[i]);            }    }    printf("%d\n",dp[S][S]);}int main(){    while(scanf("%d%d%d",&s,&m,&n)&&s){        read();        DP();    }}
0 0
原创粉丝点击