可以用二进制表示子集,这种表示方法真的非常省时间空间,其中从右往左第i位(从0开始编号)表示元素i是否在集合中(1表示“在”,0表示“不在”)
e.g.
二进制的1111换算成十进制就是15,如果用15代表全集A的话,那么1101b(b是二进制)即13d(十进制)就代表了A的一个具有第1、第3、第5个元素的子集B。

本题的做法有很多。一种相对容易实现的方法是:用两个集合s1表示恰好有一个人教的科目集合,s2表示至少有两个人教的科目集合,而d(i,s1,s2)表示已经考虑了前i个人时的最小花费。注意,把所有人一起从0编号,则编号0~m-1是在职教师,m~n+m-1是应聘者。状态转移方程为d(i,s1,s2) = min{d(i+1, s1’, s2’)+c[i], d(i+1, s1, s2)},其中第一项表示“聘用”,第二项表示“不聘用”。当i≥m时状态转移方程才出现第二项。这里s1’和s2’分别表示“招聘第i个人之后s1和s2的新值”,具体计算方法见代码。

下面代码中的st[i]表示第i个人能教的科目集合(注意输入中科目从1开始编号,而代码的其他部分中科目从0开始编号,因此输入时要转换一下)。下面的代码用到了一个技巧:记忆化搜索中有一个参数s0,表示没有任何人能教的科目集合。这个参数并不需要记忆(因为有了s1和s2就能算出s0),仅是为了编程的方便(详见s1’和s2’的计算方式)。

#include<iostream>
#include<string.h>
using namespace std;
#include<sstream>
#define maxs 10
#define maxn 130+10
#define maxm 30
#define INF 1000000000
int s,m,n,c[maxn],st[maxn],d[maxn][1<<maxs][1<<maxs];int dp(int i,int s0,int s1,int s2)
{if(i==m+n+1)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);//不选 //接下来是选这个人的情况,要更改三个集合的数值 //m0 是没有人教的课中他可以教的课 m1是恰好有一个人教的课中他可以教的课 int m0=s0&st[i];int m1=s1&st[i];s0^=m0;//集合A和AB的交集的异或等于A去掉交集s1=(s1^m1)|m0;s2|=m1; //s2是至少有两个人教的课的集合 ans=min(ans,c[i]+dp(i+1,s0,s1,s2));return ans;
}int main()
{while (~scanf("%d%d%d", &s, &m, &n) && s&&m&&n){memset(d, -1, sizeof(d));memset(st, 0, sizeof(st));getchar();for (int i = 1; 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; }else{x--;   //将科目从0开始编号st[i] |= (1 << x);  //二进制的压缩存储}}}int ans = dp(1, (1 << s) - 1, 0, 0);printf("%d\n", ans);}return 0;}

UVA 10187 校长的烦恼相关推荐

  1. Uva 10817 校长的烦恼

    题目链接:https://uva.onlinejudge.org/external/108/10817.pdf 题意:m个教师,n个应聘者,s个课程,每个人的工资为c,每个人能教一些课程.求最少的支付 ...

  2. UVa在线比赛单题汇总-----DP专题

    动态规划基础 例题 LA 3882 UVa 3882 - And Then There Was One 递推------------无力orz UVa 10635 10635 - Prince and ...

  3. NKOJ C2153「迎新春,贺新年,LJ24祝大家新年快乐」赛后总结帖by TangH

    迎新春,贺新年,LJ24祝大家新年快乐 赛后谢罪反思 LJ24TangHaoLong「唐 浩滝」 Global Igoodvegetablea LJ24新春赛,实则是冬令营状压dp完结小测.OI赛制, ...

  4. sicily题目分类

    sicily题目分类 1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. ...

  5. [sicily]部分题目分类

    sicily题目分类 1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. ...

  6. Sicily 题目分类

    依照自己水平挑着做→ →~~ 1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 ...

  7. 编程题目分类(剪辑)

    1. 编程入门 2. 数据结构 3. 字符串 4. 排序 5. 图遍历 6. 图算法 7. 搜索:剪枝,启发式搜索 8. 动态规划/递推 9. 分治/递归 10. 贪心 11. 模拟 12. 算术与代 ...

  8. 预警数据一键升级工具_重磅 | 教务管理全新升级,“章鱼校长”助力机构实现轻松管理...

    暑假开班,教务繁忙 今天小云为您送上一个重磅消息 教务管理系统「章鱼校长」全面上线啦!!! 可能会有校长问,为什么叫"章鱼校长"? 当培训机构校长太难了 要会招生.报名.排班.考勤 ...

  9. UVa Online Judge 工具網站

    UVa Online Judge 工具網站 转自http://www.csie.ntnu.edu.tw/~u91029/uva.html Lucky貓的ACM園地,Lucky貓的 ACM 中譯題目 M ...

最新文章

  1. 海外web平台访问速度慢的原因之一
  2. 机器学习(二十二)——推荐算法中的常用排序算法, Tri-training
  3. 自定义控件详解(四):Paint 画笔路径效果
  4. JS 动态创建元素、删除元素、替换元素、修改元素
  5. 折线 没有显示_动画折线图,你还可以试试这个图表
  6. 《Greenplum5.0 最佳实践》 系统监控与维护 (五)
  7. Matlab中函数imnoise使用浅谈
  8. 林业与计算机结合的sci期刊,sci收录的林业期刊有哪些
  9. echarts 画正弦曲线
  10. SLAM论文笔记---- FlowNet及FlowNet2.0
  11. Font-Awesome最新版完整使用教程
  12. 训练网络时,loss损失的问题
  13. win11本地用户和组找不到的解决办法
  14. bo耳机h5使用说明_给想浅尝便携hifi耳机的烧友的一点建议
  15. python语言通过()来体现语句逻辑关系_【单选题】Python语言通过( )来体现语句之间的逻辑关系。...
  16. 什么样的程序员才能算是一个合格的程序员呢?
  17. 南方CASS11.0.0.8最新版安装教程附下载地址
  18. linux巡检脚本生成word,windows、linux应急响应、安全巡检
  19. 来自沪江、滴滴、蘑菇街架构师的 Docker 实践分享
  20. 针对自动跳转到2345导航页流氓行为的解决办法

热门文章

  1. html复习第六天 京东首页布局(导航栏/左侧)
  2. 一些常用的数学在线计算器
  3. android 自动锁屏设置,如何才能使安卓手机不自动锁屏?改成自动黑屏,谢谢
  4. 平开式窗帘有哪些选购要点?-好佳居窗帘十大品牌
  5. 在网上疯传的行动艺术照
  6. 2017第二届上海DAC体验
  7. C/C++函数名称修饰规则及extern C的作用(函数名压扎)
  8. 图像处理的一些相关知识(Related knowledge for IQA)
  9. 你必须收藏的快速学习Autodesk最新编程接口的免费录像
  10. office使用技巧大全