zoukankan      html  css  js  c++  java
  • UVa 10817 Headmaster's Headache(状态压缩DP)

    题意:

    有一个学校想要聘请老师,要求每个学科都有两个以上的老师授课,并且要使总费用最小。有S(最多8个)个学科,现任的M(最多20个)个老师(你必须继续聘请他们),N(最多100个)份申请。后来的M行每行有至少两个整数,表示现任的老师的工资,和他所教授的课程(可能不止一个)。再后来的N行每行有也有至少两个整数表示聘请这个老师所需的费用,以及他所教授的课程(可能不止一个)。

    思路:

    http://www.cnblogs.com/staginner/archive/2011/12/07/2278727.html

    如何进行状态压缩很关键,链接中的思路有待于细细琢磨。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <climits>
    #include <cctype>
    #include <algorithm>
    using namespace std;
    
    const int MAXD = 10000;
    const int MAXN = 110;
    int s, m, n;
    int dp[MAXN][MAXD];
    int need[12], tech[MAXN][12], state[12];
    int cost[MAXN];
    
    void solve()
    {
        for (int i = 1; i <= s; ++i)
            need[i] = 2;
    
        char b[100];
        int v = 0;
        for (int i = 0; i < m; ++i)
        {
            gets(b);
            int k = strlen(b);
            int t;
            sscanf(b, "%d", &t);
            v += t;
    
            int j = 0;
            while (isdigit(b[j]))
                ++j;
    
            for (++j; j < k; ++j)
            {
                sscanf(&b[j], "%d", &t);
                if (need[t])
                    --need[t];
    
                while (isdigit(b[j]))
                    ++j;
            }
        }
    
        memset(tech, 0, sizeof(tech));
        for (int i = 1; i <= n; ++i)
        {
            gets(b);
            int k = strlen(b);
            int t;
            sscanf(b, "%d", &t);
            cost[i] = t;
    
            int j = 0;
            while (isdigit(b[j]))
                ++j;
    
            for (++j; j < k; ++j)
            {
                sscanf(&b[j], "%d", &t);
                tech[i][t] = 1;
    
                while (isdigit(b[j]))
                    ++j;
            }
        }
    
        memset(dp, 0x3f, sizeof(dp));
        int P = 0;
        for (int i = 1; i <= s; ++i)
            P = 3 * P + 2;
    
        for (int i = 0; i <= P; ++i)
        {
            int t = i;
            for (int j = 1; j <= s; ++j)
                state[j] = t % 3, t /= 3;
            int j;
            for (j = 1; j <= s && state[j] >= need[j]; ++j);
            if (j == s + 1)
                dp[0][i] = v;
        }
    
        for (int i = 1; i <= n; ++i)
        {
            for (int j = 0; j <= P; ++j)
            {
                int t = j;
                for (int k = 1; k <= s; ++k)
                    state[k] = t % 3, t /= 3;
    
                for (int k = 1; k <= s; ++k)
                    if (tech[i][k] && state[k] < 2)
                        ++state[k];
    
                t = 0;
                for (int k = s; k >= 1; --k)
                    t = 3 * t + state[k];
    
                dp[i][j] = min(dp[i-1][j], dp[i-1][t] + cost[i]);
            }
        }
    }
    
    int main()
    {
        char b[100];
        while (gets(b))
        {
            sscanf(b, "%d %d %d", &s, &m, &n);
            if (!s)
                break;
            
            solve();
            printf("%d\n", dp[n][0]);
        }
    
        return 0;
    }
    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    Cf的一些总结
    Goodbye 2019
    牛客多校第8场 A题
    19牛客多校第二场 H题
    Hihocoder1673
    记一次根据图片原尺寸设置样式,并进行缩放和拖拽
    鱼骨时间轴案例(转自CSDN,原文链接附于文中)
    jQuery横向上下排列鱼骨图形式信息展示代码时光轴样式(转自CSDN,原文链接附于文中)
    mxGraph实现鱼骨图(因果图)(转自CSDN,链接附于文中)
    erlang win64位包下载链接
  • 原文地址:https://www.cnblogs.com/kedebug/p/2788758.html
Copyright © 2011-2022 走看看