uva 10817(数位dp)

某校有m个教师和n个求职者,需讲授s个课程(1<=s<=8, 1<=m<=20, 1<=n<=100)。已知每人的工资c(10000<=c<=50000)和能教的课程集合,要求支付最少的工资使得每门课都至少有两名教师能教。在职教师不能辞退。

用两个集合,s1表示恰好有一个人教的科目集合,s2表示至少有两个人教的科目集合。设计状态\(d(i, s1, s2)\)表示考虑了后n-i个人时的最小花费。把所有人从1到n+m编号,那么m~n+m-1表示应聘者。因此,状态转移方程为\(d(i, s1, s2)=min\{d(i+1, s1', s2')+c[i], d(i+1, s1, s2)\}\),其中第二项只能在应聘者中使用。s1‘和s2’分别表示招聘第i个人之后s1和s2的新值。具体计算方式见代码。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxs=8, maxn=125, INF=1e9;
int s, m, n, t, c[maxn], st[maxn];
int f[maxn][1<<maxs][1<<maxs]; //[0, 1<<n)正好表示n个元素的所有子集
//c:每个人的工资 st:每个人教授的科目集合
char ch; int d(int cur, int s0, int s1, int s2){ //si:有i个人教授的科目集合
if (cur==n) return (s2+1==(1<<s)?0:INF);
int &ans=f[cur][s1][s2];
if (ans>=0) return ans; ans=INF; //必须要>=0!
if (cur>=m) ans=min(ans, d(cur+1, s0, s1, s2)); //不买这个人
s2^=s1&st[cur]; s1^=s1&st[cur];
s1^=s0&st[cur]; s0^=s0&st[cur]; //如果选了这个人
ans=min(ans, d(cur+1, s0, s1, s2)+c[cur]);
return ans;
} int main(){
while (~scanf("%d%d%d", &s, &m, &n)&&s){
n=n+m; memset(f, -1, sizeof(f));
memset(st, 0, sizeof(st));
for (int i=0; i<n; ++i){
scanf("%d%c", &c[i], &ch);
while (ch!='\n'){
scanf("%d%c", &t, &ch);
st[i]|=(1<<(t-1));
}
}
printf("%d\n", d(0, (1<<s)-1, 0, 0));
}
return 0;
}

uva 10817(数位dp)的更多相关文章

  1. [uva 1350]数位dp+二分

    题目链接:https://vjudge.net/problem/38405 #include<bits/stdc++.h> using namespace std; ][]; ]; lon ...

  2. uva 10712 - Count the Numbers(数位dp)

    题目链接:uva 10712 - Count the Numbers 题目大意:给出n,a.b.问说在a到b之间有多少个n. 解题思路:数位dp.dp[i][j][x][y]表示第i位为j的时候.x是 ...

  3. 状压DP UVA 10817 Headmaster's Headache

    题目传送门 /* 题意:学校有在任的老师和应聘的老师,选择一些应聘老师,使得每门科目至少两个老师教,问最少花费多少 状压DP:一看到数据那么小,肯定是状压了.这个状态不好想,dp[s1][s2]表示s ...

  4. UVa 1009 Sharing Chocolate (数位dp)

    题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  5. 【数位dp】UVA - 11361 - Investigating Div-Sum Property

    经典数位dp!而且这好像是数位dp的套路板子……不需要讨论原来我很头疼的一些边界. 改天用这个板子重做一下原来的一些数位dp题目. http://blog.csdn.net/the_useless/a ...

  6. UVA - 1640 The Counting Problem (数位dp)

    题意:统计l-r中每种数字出现的次数 很明显的数位dp问题,虽然有更简洁的做法但某人已经习惯了数位dp的风格所以还是选择扬长避短吧(说白了就是菜啊) 从高位向低位走,设状态$(u,lim,ze)$表示 ...

  7. UVA 10817 十一 Headmaster's Headache

    Headmaster's Headache Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Sub ...

  8. 数位dp总结 之 从入门到模板

    转发自WUST_WenHao巨巨的博客 基础篇 数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数.所谓数位dp,字面意思就是在数位上进行dp咯.数位还算是比较好听 ...

  9. 【BZOJ1662】[Usaco2006 Nov]Round Numbers 圆环数 数位DP

    [BZOJ1662][Usaco2006 Nov]Round Numbers 圆环数 Description 正如你所知,奶牛们没有手指以至于不能玩"石头剪刀布"来任意地决定例如谁 ...

随机推荐

  1. PHP不用第三变量交换2个变量的值的解决方法

    以前做过一道php面试题是这样的:不使用第三个变量实现交换两个变量的值.一般都是借助第三个中间变量来实现原来两个变量的值交换,但是这道题却要求不能使用中间变量,这对于初学者来说也算是一个难题了.网上找 ...

  2. poj3352 边-双联通分量

    题意:给一个无向图,问最少加几条边变成边-双联通 题解:求一次双联通,缩点,这样就变成了一棵树,结果就是(树上的叶子节点+1)/2,叶子节点可以通过入度判断 #include<map> # ...

  3. 【二叉树的递归】02二叉树的最大深度【Maximum Depth of Binary Tree】

    ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 给定一个二叉树,找出他的最小的深度 ...

  4. XML的二十个热点问题

    这些日子,几乎每个人都在谈论XML (Extensible Markup Language),但是很少有人真正理解其含义.XML的推崇者认为它能够解决所有HTML不能解决的问题,让数据在不同的操作系统 ...

  5. Parallel Programming-Parallel.Invoke

    本文主要介绍Parallel.Invoke的使用. 一.使用例子 class ParallelInvoke { public void Action1() { Thread.Sleep(); Cons ...

  6. BZOJ4695:最假女选手

    浅谈区间最值操作和历史最值问题:https://www.cnblogs.com/AKMer/p/10225100.html 题目传送门:https://lydsy.com/JudgeOnline/pr ...

  7. MySQL复制--最快的从库搭建方法(tar包) -转

    最快的从库搭建方法0,准备从库第一次数据备份,临时锁所有表开启窗口1 mysql> flush tables with read lock; Query OK, 0 rows affected  ...

  8. MySQL Explain详解(转)

    explain SELECT a.* FROM test a,(select id from test where level_id <=4 order by aa_id limit 24300 ...

  9. puppet多环境配置(puppet自动化系列2)

    三.Puppet多环境部署 我们为puppetmaster建立3个环境,它们分别是开发环境(jqdev).测试环境(jqtest).生产环境(jqprd). 3.1 配置puppet.conf 在标签 ...

  10. 问题15:如何判断字符串a是否以字符串b开头或结尾

    方法一:使用正则表达式的^和$实现 '^000':表示,只匹配字符串的开头,若开头是 '000' ,则返回 ['000'] : '000$':表示,只匹配字符串的结尾,若结尾是 '000' ,则返回 ...