uva10817集合dp

题意:某校有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;
}
时间: 2024-08-23 23:01:45

uva10817集合dp的相关文章

Headmaster&#39;s Headache UVa10817【DP】(缺)

题目: The headmaster of Spring Field School is considering employing some new teachers for certain subjects. There are a number of teachers applying for the posts. Each teacher is able to teach one or more subjects. The headmaster wants to select appli

bzoj2064: 分裂(集合DP)

......咸鱼了将近一个月,因为沉迷ingress作业越来越多一直没时间搞OI呜呜呜 题目大意:有一个初始集合(n个元素)和一个目标集合(m个元素)(1<=n,m<=10),两个操作   操作①将集合里的两个数合成一个数   操作②将集合的一个数分成两个数 问对初始集合最少进行几次操作可以到达目标集合 ...从来没做过集合DP题,看见这题一脸懵逼>_< 看了题解之后目瞪口呆,思路又神,又学会了新技巧(可能是我以前比较傻才不会QAQ 显然最多的次数就是将初始集合全部合成一个数然后再

集合DP 点集匹配问题

刘汝佳大白书p61页 #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <iostream> using namespace std; #define INF 0x3f3f3f3f #define N 21 struct point { double x, y, z; } P[N]; double x[N], y[N]; doub

E. The Values You Can Make 背包,同时DP

http://codeforces.com/problemset/problem/688/E 题目需要在n个数中找出一个集合,使得这个集合的和为val,然后问这些所有集合,能产生多少个不同的和值. 题解是直接两个同时dp,设dp[j][h]表示主集合的和为j,能否产生h这个数字. 把他们看作是两个集合,对于每个数,都可以放在第一个集合,或者放在第一个集合后,再放入第二个集合. #include <cstdio> #include <cstdlib> #include <cst

poj 2836 Rectangular Covering(状态压缩dp)

Description n points are given on the Cartesian plane. Now you have to use some rectangles whose sides are parallel to the axes to cover them. Every point must be covered. And a point can be covered by several rectangles. Each rectangle should cover

(状压dp)ABC 067 F : Mole and Abandoned Mine

Mole decided to live in an abandoned mine. The structure of the mine is represented by a simple connected undirected graph which consists of N vertices numbered 1through N and M edges. The i-th edge connects Vertices ai and bi, and it costs ciyen (th

杭电ACM分类

杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDIATE DECODABILITY

368. Largest Divisible Subset

/* * 368. Largest Divisible Subset * 2016-7-16 by Mingyang * 和LIS很相似,dp[i]表示nums数组从0到i的最大集合的size. * 这题应该分成两个问题:得到最大集合size,输出这个集合 * 对于第一个问题,最大集合size就是dp数组的最大值,可以边画表边维护一个当前最大值; * 对于第二个问题,我们要维护一个parent数组,记录nums[i]加入到了哪个集合; * dp[i] = max(dp[i], dp[j] + 1

【转】对于杭电OJ题目的分类

[好像博客园不能直接转载,所以我复制过来了..] 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze 广度搜索1006 Redraiment猜想 数论:容斥定理1007 童年生活二三事 递推题1008 University 简单hash1009 目标柏林 简单模拟题1010 Rails 模拟题(堆栈)1011 Box of Bricks 简单题1012 IMMEDI