UVA10817 Headmaster's Headache

链接:UVA10817

题意:需要讲s个课程,现在有m个老师和n个应聘的,要求没门课最少有两名老师,求出最少支付的工资。

状压DP。。。。。用一个三维数组d[i][s1][s2],i表示第i个老师(or应聘者),s1表示恰好有一个人教的科目的集合,s2表示至少有两个教科目的集合,i表示考虑前i个人的情况。。

然后记忆化搜索,当搜到i为n+m时,如果s2还不是(1<<s)-1,就说明不可能满足题目要求(在这题一定满足的)。。。

转移方程是,d(i,s1,s2)=min(d(i+1,s1',s2')+c[i],d(i+1,s1,s2));...。第一种状态表示聘用i,第二种表示不用,第二种只有当i>=m时才有。

位运算:&表示寻找一个元素是否在这个集合,|表示加进这个集合,^表示去掉。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=125;
const int INF=1<<30;
int m,n,s,st[MAXN],d[MAXN][1<<8][1<<8],c[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=min(ans,dp(i+1,s0,s1,s2));
    int m0=st[i]&s0,m1=st[i]&s1;
    s0^=m0,s1=(s1^m1)|m0,s2|=m1;
    ans=min(ans,c[i]+dp(i+1,s0,s1,s2));
    return ans;
}
int main()
{
    int i;
    while(scanf("%d%d%d",&s,&m,&n)!=EOF&&s)
    {
        int x;
        memset(d,-1,sizeof(d));
        memset(st,0,sizeof(st));
        for(i=0;i<m;i++)
        {
            scanf("%d",&c[i]);
            while(1)
            {
                char ch;
                scanf("%d",&x);
                st[i]|=(1<<(x-1));
                ch=getchar();
                if(ch=='\n')
                    break;
            }
        }
        for(i=m;i<m+n;i++)
        {
            scanf("%d",&c[i]);
            while(1)
            {
                char ch;
                scanf("%d",&x);
                st[i]|=(1<<(x-1));
                ch=getchar();
                if(ch=='\n')
                    break;
            }
        }
        int ans=dp(0,(1<<s)-1,0,0);
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值