UVA 10817 Headmaster's Headache - 状压dp
2016-03-20 12:02
411 查看
题目描述
(1<=s<=8,1<=m<=20,1<=n<=100 )。
已知每人的工资c(10000<=c<=50000)和能教的课程集合,要求支付最少的工资使得每门课都至少有两名教师能教。在职教师不能辞退。
(参考网上题解)
题目大意:
某校有m个在职教师和n个求职者,需讲授s个课程(1<=s<=8,1<=m<=20,1<=n<=100 )。
已知每人的工资c(10000<=c<=50000)和能教的课程集合,要求支付最少的工资使得每门课都至少有两名教师能教。在职教师不能辞退。
(参考网上题解)
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; #define MAXS 8 #define MAXM 20 #define MAXN 100 #define INF 2000000000 #define MAXST 256 int n,m,a[MAXN+MAXM+10],cnt[MAXS+10],st1,st2,sum,cost[MAXN+MAXM+10],s,S; int dp[MAXST+10][MAXST+10]; void read() { char c; st1=st2=0,sum=0; memset(cnt,0,sizeof cnt); memset(a,0,sizeof a); for(int i=1;i<=n+m;i++){ scanf("%d",&cost[i]); while(c=getchar(),c!='\n'){ if(c>='0'&&c<='9'){ a[i]|=(1<<(c-'0'-1)); if(i<=m) cnt[c-'0']++; } } if(i<=m){ sum+=cost[i]; st1|=a[i]; } } for(int i=1;i<=s;i++) if(cnt[i]>=2) st2|=(1<<(i-1)); S=(1<<s)-1; } void DP() { for(int i=S;i>=0;i--) for(int j=S;j>=0;j--) dp[i][j]=INF; //dp[至少有一个人教][至少有两个人教] dp[st1][st2]=sum; for(int i=m+1;i<=n+m;i++){ for(int j=S;j>=0;j--) for(int k=S,s1,s2;k>=0;k--){ if(dp[j][k]==INF) continue; s1=j|a[i]; s2=(j&a[i])|k; dp[s1][s2]=min(dp[s1][s2],dp[j][k]+cost[i]); } } printf("%d\n",dp[S][S]); } int main() { while(scanf("%d%d%d",&s,&m,&n)&&s){ read(); DP(); } }
相关文章推荐
- 第4周-项目5-(3)
- Volley的使用(三)
- Category(类别)和扩展(Extension)的区别
- 两颗线段树
- python常用数学函数
- 多线程“基础篇”04之 synchronized关键字
- VIM学习笔记 缩进 (Indent)
- Spark 1.X DatandaLone伪分布环境搭建
- Android 通用标题栏简单封装实现
- 在centos 7上装载php7.0.2、mysql 5.7.11 和 nginx-1.9.12
- 上百个Android开源项目分享
- Running Android Lint has encountered a... Failed. java.lang.NullPointerException
- Git使用
- 【mahapps.metro】如何快速让WPF窗体具有Metro扁平化风格
- 第四周项目三 猜数字游戏
- SciTE 编辑器汉化
- 夯实基础——static关键字
- C语言之辗转相除法
- 强力删除文件代码
- Gym 100015A Another Rock-Paper-Scissors Problem