码迷,mamicode.com
首页 > 其他好文 > 详细

uva10817集合dp

时间:2016-07-21 19:38:09      阅读:112      评论:0      收藏:0      [点我收藏+]

标签:

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

思路:d(i,s0,s1,s2)表示已经雇了i个人且授课状态为(s0,s1,s2),还需要多少钱。其中s0表示没有人授课的课程集合,s1表示只有一个人授课的课程集合,s2表示有2个老师授课的课程集合。(因为不知道要雇佣多少老师,所以状态为当雇佣了i人时还需要多少钱,而不是雇佣了i人花了多少钱)。技术分享

 

#include<bits/stdc++.h>
using namespace std;

#define maxn 150
#define maxs 10
#define inf 0x3f3f3f3f
int m,n,s;
int c[maxn],st[maxn];
int d[maxn][1<<maxs][1<<maxs];

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;
    int m1=st[i]&s1;
    s0^=m0;
    s1=(s1^m1)|m0;
    s2|=m1;
    ans=min(ans,dp(i+1,s0,s1,s2)+c[i]);
    return ans;
}

int main()
{
    while(~scanf("%d%d%d",&s,&m,&n)&&m&&n&&s)
    {
        getchar();
        memset(d,-1,sizeof(d));
        memset(st,0,sizeof(st));
        for(int i=0;i<m+n;i++)
        {
            string str;
            getline(cin,str);
            stringstream ss(str);
            int x,flag=1;
            while(ss>>x)
            {
                if(flag){flag=0;c[i]=x;continue;}
                x--;
                st[i]|=(1<<x);
            }
        }
        dp(0,(1<<s)-1,0,0);
        printf("%d\n",d[0][0][0]);
    }
    return 0;
}

 

 


uva10817集合dp

标签:

原文地址:http://www.cnblogs.com/mu-ye/p/5692721.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!