UVA - 10817 Headmaster's Headache(状压DP)

题目链接:https://vjudge.net/problem/UVA-10817

题意:某校有n个教师和m个求职者,已知每人的工资和能教的课程集合,要求支付最少的工资使得每门课都至少有两名教师教学,

在职教师必须招聘。

AC代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=1<<30;
int s,m,n;
int st[130],c[130];
int d[130][300][300];
int dp(int i,int s0,int s1,int s2){//第i个人 没有教过的集合s0 一个人教过的s1 两个人教过的s2
    if(i==m+n)   return s2==(1<<s)-1? 0:INF;
    int &ans=d[i][s1][s2];  //  记忆化搜索
    if(ans>=0)   return ans;
    int ans=INF;
    if(i>=m) ans=dp(i+1,s0,s1,s2);
    int m0=s0&st[i],m1=st[i]&s1;
    s0=s0^m0;
    s1=(s1^m1)|m0;
    s2=s2|m1;
    ans=min(ans,c[i]+dp(i+1,s0,s1,s2));
    return ans;
}
int main(){
    while(scanf("%d%d%d",&s,&m,&n)!=EOF&&s){
        getchar();
        memset(st,0,sizeof(st));
        memset(c,0,sizeof(c));
        memset(d,-1,sizeof(d));
        char ch[130];
        for(int i=0;i<m;i++){
            gets(ch);
            sscanf(ch,"%d",&c[i]);
            int len=strlen(ch);
            for(int j=6;j<len;j++)//6代表为工资与空格所占位数
                if(isdigit(ch[j]))
                {
                    int x;
                    sscanf(ch+j,"%d",&x);
                    st[i]=st[i]|(1<<(x-1));
                }
        }
        for(int i=m;i<m+n;i++){
            gets(ch);
            sscanf(ch,"%d",&c[i]);
            int len=strlen(ch);
            for(int j=6;j<len;j++)
                if(isdigit(ch[j]))
                {
                    int x;
                    sscanf(ch+j,"%d",&x);
                    st[i]=st[i]|(1<<(x-1));
                }
        }
        int ans=dp(0,(1<<s)-1,0,0);
        printf("%d\n",ans);
    }
}

  

 

posted @   ccsu_dj辉  阅读(132)  评论(1编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示