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. 分布式系统的Raft算法——在失联阶段这个老Leader的任何更新都不能算commit,都回滚,接受新的Leader的新的更新 意味着还是可能丢数据!!!

    过去, Paxos一直是分布式协议的标准,但是Paxos难于理解,更难以实现,Google的分布式锁系统Chubby作为Paxos实现曾经遭遇到很多坑. 来自Stanford的新的分布式协议研究称为R ...

  2. 多线程、方便扩展的Windows服务程序框架

    多线程.方便扩展的Windows服务程序框架 吴剑 2012-06-02 转载请注明出处:http://www.cnblogs.com/wu-jian/ 前言 在项目应用中经常会碰到定时调度的工作,比 ...

  3. HDU 6231 (K-th Number)

    题目链接:https://cn.vjudge.net/problem/HDU-6231 思路:二分+双指针: #include <stdio.h> #include <iostrea ...

  4. 把自定义的demuxer加入ffmpeg源码

    .简介:把上一篇文章中的demuxer加入ffmpeg源码中去,使可以用命令行方式调用自定义的demuxer 第一步: 在libavformat目录下新建mkdemuxer.c和mkdemuxer.h ...

  5. POJ1741 Tree(树的点分治基础题)

    Give a tree with n vertices,each edge has a length(positive integer less than 1001).Define dist(u,v) ...

  6. ACM学习历程—BestCoder Round #75

    1001:King's Cake(数论) http://acm.hdu.edu.cn/showproblem.php?pid=5640 这题有点辗转相除的意思.基本没有什么坑点. 代码: #inclu ...

  7. 系列文章--Node.js学习笔记系列

    Node.js学习笔记系列总索引 Nodejs学习笔记(一)--- 简介及安装Node.js开发环境 Nodejs学习笔记(二)--- 事件模块 Nodejs学习笔记(三)--- 模块 Nodejs学 ...

  8. 找工作-——网络IO

    网络层 主要任务是把网络协议数据单元或分组从源计算机经过适当的路径发送到目的地计算机.从源计算机到目的计算机可能要经过若干个中间节点,这需要在通信子网中进行路由选择. 网络层与数据链路层有很大的差别, ...

  9. Django-进阶 分页,中间件

    知识预览 分页 中间件 回到顶部 分页 Django的分页器(paginator) view from django.shortcuts import render,HttpResponse # Cr ...

  10. Python 写文件时的Unicode设置

    今天在把Evenote的笔记内容写为文件时出错:     f.write(content) UnicodeEncodeError: &apos;gbk&apos; codec can& ...