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


    UVA-10817- Headmaster's Headache

    题意:

    这间学校开设S门课,给出校长已经有的师资n,然后再给出m个应聘者,每门课至少有两名任课老师,求最少需要的雇佣工资。

    分析:

    这个题的输入很奇怪,每个人的信息输入在一行上,不能简单地读取,需要用字符串处理操作。

    已经有的师资是肯定要的,而对于求职者可以要可以不要,第一纬度状态就是当前的人,如果第二维度是开设的开设的课程的话,那么要把有一个老师任课的课程和有两个老师以上任课的课程都作为状态。

    • 位运算操作很重要,状压dp中状态转移,集合之间的交并集的处理很关键。
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 130;
    const int INF = 1<<20;
    int s,m,n,x;
    int d[maxn][1<<8][1<<8];
    int c[maxn],st[maxn];
    int dp(int i,int s0,int s1,int s2)
    {
        if(i==m+n)
            return s2 == (1<<s)-1 ? 0:INF;
        int &ans = d[i][s1][s2];
        if(ans>=0) return ans;
        ans = INF;
        if(i>=m)//不选当前求职者
            ans = dp(i+1,s0,s1,s2);
        int m0 = st[i] & s0;//没人讲的课中i可以讲的
        int m1 = st[i] & s1;//有一个人讲的课中,i可以讲的
        s0 ^= m0;//把s0中消去i讲的
        s1 = (s1 ^ m1) | m0;//把s1中去除i讲的m1,添加i讲的m0
        s2 |= m1;//添加i讲的m1到s2集合
        ans = min(ans,c[i]+dp(i+1,s0,s1,s2));
        return ans;
    }
    int main()
    {
        string str;
        while(getline(cin,str))
        {
            memset(st,0,sizeof st);
            //下面是字符串流操作,每次输入一行的内容到str
            stringstream ss(str);
            ss>>s>>m>>n;
            if(s==0)
                break;
            for(int i=0;i<m+n;i++)
            {
                getline(cin,str);stringstream ss(str);
                ss>>c[i];
                while(ss>>x)
                    st[i] |= 1<<(x-1);
            }
            memset(d,-1,sizeof d);
            int ans = dp(0,(1<<s)-1,0,0);
            cout<<ans<<endl;
        }
        return 0;
    }
    
  • 相关阅读:
    字体
    当前li的同级且不包含当前li
    溢出用省略号显示
    .NET Core中使用Cookie步骤
    .NET Core中使用Session步骤
    asp.net core 读取配置
    Asp.Net Core run on Ubuntu
    .net core中使用GB2312编码
    ubuntu mysql 安装
    samba的安装
  • 原文地址:https://www.cnblogs.com/1625--H/p/9902598.html
Copyright © 2020-2023  润新知