• UVA


    题意:有M个已聘教师,N个候选老师,S个科目,已知每个老师的雇佣费和可教科目,已聘老师必须雇佣,要求每个科目至少两个老师教的情况下,最少的雇佣费用。

    分析:

    1、为让雇佣费尽可能少,雇佣的老师应教他所能教的所有科目。

    2、已聘老师必须选,候选老师可选可不选。

    3、dfs(cur, subject1, subject2)---求出在当前已选cur个老师,有一个老师教的科目状态为 subject1,有两个及以上老师教的科目状态为 subject2的情况下,最少的雇佣费用。

    dp[cur][subject1][subject2]---在当前已选cur个老师,有一个老师教的科目状态为 subject1,有两个及以上老师教的科目状态为 subject2的情况下,最少的雇佣费用。

    4、如果第cur个老师选择,则若他能教的科目和在subject1中所对应的科目都为1,那将该科目变为能被两个老师教。

    subject1 & teacher[cur] --- 筛选出这个老师能教的科目中,目前只有一个老师教的科目---让这个老师去教这些科目的话,这些科目就被两个老师教了。

    subject2 |= (subject1 & teacher[cur]);---将能被两个老师教的科目并到集合里。

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<cmath>
    #include<iostream>
    #include<sstream>
    #include<iterator>
    #include<algorithm>
    #include<string>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    #include<deque>
    #include<queue>
    #include<list>
    #define lowbit(x) (x & (-x))
    const double eps = 1e-8;
    inline int dcmp(double a, double b){
        if(fabs(a - b) < eps) return 0;
        return a > b ? 1 : -1;
    }
    typedef long long LL;
    typedef unsigned long long ULL;
    const int INT_INF = 0x3f3f3f3f;
    const int INT_M_INF = 0x7f7f7f7f;
    const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
    const LL LL_M_INF = 0x7f7f7f7f7f7f7f7f;
    const int dr[] = {0, 0, -1, 1, -1, -1, 1, 1};
    const int dc[] = {-1, 1, 0, 0, -1, 1, -1, 1};
    const int MOD = 1e9 + 7;
    const double pi = acos(-1.0);
    const int MAXN = 120 + 10;
    const int MAXT = 300 + 10;
    using namespace std;
    int cost[MAXN];
    int teacher[MAXN];
    int dp[MAXN][MAXT][MAXT];
    string s;
    int S, M, N;
    int dfs(int cur, int subject1, int subject2){
        if(cur == M + N){
            return subject2 == (1 << S) - 1 ? 0 : INT_INF;
        }
        int &ans = dp[cur][subject1][subject2];
        if(ans >= 0) return ans;
        ans = INT_INF;
        if(cur >= M) ans = dfs(cur + 1, subject1, subject2);//第cur个老师不选
        subject2 |= (subject1 & teacher[cur]);//第cur个老师选
        subject1 |= teacher[cur];//将这个老师能教的科目中,目前没人教的科目,让他教
        ans = min(ans, cost[cur] + dfs(cur + 1, subject1, subject2));
        return ans;
    }
    int main(){
        while(scanf("%d%d%d", &S, &M, &N) == 3){
            if(!S && !M && !N) return 0;
            for(int i = 0; i < M + N; ++i){
                scanf("%d", &cost[i]);
                getline(cin, s);
                stringstream ss(s);
                int x;
                teacher[i] = 0;
                while(ss >> x){
                    teacher[i] |= 1 << (x - 1);
                }
            }
            memset(dp, -1, sizeof dp);
            printf("%d
    ", dfs(0, 0, 0));
        }
        return 0;
    }
    

      

  • 相关阅读:
    09.回文数
    08.字符串转换位整数
    背景图片自适应
    认证 (authentication) 和授权 (authorization) 的区别
    vue-组件之间传值
    数组对象去重
    二进制数转换十进制数
    node-删除对象中指定属性失效问题-JSON.parse实例化
    Vue-动态修改数组
    正则遇到的问题集合
  • 原文地址:https://www.cnblogs.com/tyty-Somnuspoppy/p/7363814.html
Copyright © 2020-2023  润新知