UVa10817 Headmaster's headache[状压DP]

来源:互联网 发布:淘宝ecco鞋真假 编辑:程序博客网 时间:2024/06/05 22:58

最后再跟自己强调一次,Think twice,code once.
Headmaster’s Headache
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.
Sample Input
2 2 2
10000 1
20000 2
30000 1 2
40000 1 2
0 0 0
Sample Output
60000

题意:
给定m个必选和n个可选,每个选择都有代价和能力点,求代价最小且每个能力点都至少有2的配置。
分析:
典型DP,F[i][j]存至少有1个点的状态,J存至少有2个点的状态,数组存最小代价。
没有RE了好开心,感谢Qwsin小天使QAQ,女票最厉害了QAQ。 不过TLE了(扶额),我看了一下感觉不是常数的问题,因为我为了改RE本来就特意和std写得差不多,而且std也很快常数不应该那么大。

#include<cstdio>#include<iostream>#include<cmath>#include<cstdlib>#include<cstring>#include<string>#include<algorithm>#include<queue>#include<set>#include<map>#include<stack>#include<vector>#include<ctime>#define ll long long #define inf 0x3f3f3f3f#define modd 1e9+7#define clr(x) memset(x,0,sizeof(x))#define maxen(x) memset(x,127,sizeof(x))#define maxer(x) memset(x,0x3f,sizeof(x))#define minus(x) memset(x,-1,sizeof(x))#define each(i,n) for(int i=1;i<=n;i++)#define minn(a,b,c) min(a,min(b,c))#define maxx(a,b,c) max(a,max(b,c))#ifdef WIN32#define lld "%I64d"#else#define lld "%lld"#endif#define PROC "UVa10817"//for(int i=1;i<=n;i++)//(double) (ll) LL (int)//(double)clock()/CLOCKS_PER_SECusing namespace std;const int Maxn=150;int s,m,n,st1,st2,sum,costy[Maxn],subj[Maxn],f[1<<8][1<<8];int cnt[15];int read(){    int x=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}void read(int cur){    char tmp=getchar();    while(tmp!='\n'){    if(tmp<='9'&&tmp>='0')    subj[cur]|=1<<(tmp-'0'-1);    if(cur<=m)cnt[tmp-'0'-1]++;    tmp=getchar();    }    if(cur<=m){        st1|=subj[cur];        sum+=costy[cur];}}void init(){    s=read();m=read();n=read();    st1=0;st2=0;sum=0;clr(cnt);    each(i,m+n){        subj[i]=0;        costy[i]=read();        read(i);    }    for(int i=0; i<s; ++i)      if(cnt[i] > 1) st2 |= (1<<i);    maxer(f);}void work(){        f[st1][st2]=sum;        for(int i=m+1;i<=n+m;i++)        for(int s1=(1<<s)-1;s1>=0;s1--)        for(int s2=(1<<s)-1;s2>=0;s2--){            if(f[s1][s2] >= inf) continue;                int st1 = (subj[i]|s1);                int st2 = (subj[i]&s1) | s2;                f[st1][st2] = min(f[st1][st2], f[s1][s2]+costy[i]);        }        printf("%d\n",f[(1<<s)-1][(1<<s)-1]);}void debug(){    //}int main(){    freopen(PROC".in","r",stdin);//  freopen(PROC".out","w",stdout);    while(1){    init();    if(s)    work();    else break;    }    //debug();    return 0;}
0 0
原创粉丝点击