Uva 10817 Headmaster's Headache (DP+ 状态压缩)
来源:互联网 发布:扒皮吧软件 编辑:程序博客网 时间:2024/06/05 21:48
Problem D: Headmaster's Headache
Time limit: 2 seconds
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 applicants so that each subject is taught by at least two teachers, and the overall cost is minimized.
Input
The input consists of several test cases. The format of each of them is explained below:
The first line contains three positive integers S, M andN. S (≤ 8) is the number of subjects, M (≤ 20) is the number of serving teachers, and N (≤ 100) is the number of applicants.
Each of the following M lines describes a serving teacher. It first gives the cost of employing him/her (10000 ≤ C ≤ 50000), followed by a list of subjects that he/she can teach. The subjects are numbered from 1 to S. You must keep on employing all of them.After that there are N lines, giving the details of the applicants in the same format.
Input is terminated by a null case where S = 0. This case should not be processed.
Output
For each test case, give the minimum cost to employ the teachers under the constraints.
Sample Input
2 2 210000 120000 230000 1 240000 1 20 0 0
Sample Output
60000
题意:有一个学校想要聘请老师,要求每个学科都有两个以上的老师授课,并且要使总
费用最小。有S(最多8个)个学科,现任的M(最多20个)个老师(你必须继续聘请他
们),N(最多100个)份申请。后来的M行每行有至少两个整数,表示现任的老师的工
资,和他所教授的课程(可能不止一个)。再后来的N行每行有也有至少两个整数表示
聘请这个老师所需的费用,以及他所教授的课程(可能不止一个)。
思路:因为要使每个学科都有两个以上的老师授课,所以不能用普通二进制表示。即可
以将每门学科的上课情况用二位二进制数表示。
即 将八位扩充为16位 具体细节看代码。
#include <iostream>#include <cstdio>#include <cstring>#include <climits>#include <sstream>#include <string>#include <vector>using namespace std;const int inf=INT_MAX;const int M=110;const int N=16;vector <int> G[M];int dp[M][1<<N],cost[M];int s,n,m,num,sum,len;void initial(){ len=1<<(2*s); for(int i=0;i<=n;i++) for(int j=0;j<len;j++) dp[i][j]=inf; for(int i=0;i<=n;i++) G[i].clear(); sum=num=0;}void input(){ string str; int x; getchar(); for(int i=0;i<m;i++) { getline(cin,str); stringstream ss(str); ss>>x; sum+=x; while(ss>>x) { int one=2*x-2,two=2*x-1; if(num & 1<<one) num |=(1<<two); else num |= (1<<one); } } for(int i=1;i<=n;i++) { getline(cin,str); stringstream ss(str); ss>>cost[i]; while(ss>>x) G[i].push_back(x); }}bool judge(int p,int q){ for(int i=0;i<G[q].size();i++) { int one=2*G[q][i]-2,two=2*G[q][i]-1; if(!(p & 1<<one) || !(p & 1<<two)) return true; } return false;}void solve(){ dp[0][num]=sum; for(int i=1;i<=n;i++) for(int j=0;j<len;j++) { dp[i][j]=min(dp[i][j],dp[i-1][j]); if(dp[i-1][j]==inf) continue; if(judge(j,i)) { int t=j; for(int k=0;k<G[i].size();k++) { int one=2*G[i][k]-2,two=2*G[i][k]-1; if(t & 1<<one) t |=(1<<two); else t |= (1<<one); } dp[i][t]=min(dp[i][t],dp[i-1][j]+cost[i]); } } printf("%d\n",dp[n][len-1]);}int main(){ while(scanf("%d %d %d",&s,&m,&n)!=EOF) { if(s==0) break; initial(); input(); solve(); } return 0;}
- uva 10817 - Headmaster's Headache ( 状态压缩dp)
- UVa 10817 - Headmaster's Headache (简单DP 状态压缩)
- Uva 10817 Headmaster's Headache (DP+ 状态压缩)
- uva 10817 - Headmaster's Headache ( 状态压缩dp)
- UVA 10817-Headmaster’s Headache(状态压缩DP)
- UVa 10817 - Headmaster's Headache ( 状态压缩dp)
- Uva 10817 - Headmaster's Headache(状态压缩DP)
- UVA - 10817 Headmaster's Headache 状态压缩
- UVA 10817 Headmaster's Headache(dp 状态压缩 01背包)
- 10817 - Headmaster's Headache(状态压缩)
- Headmaster's Headache - UVa 10817 状压dp
- UVa 10817 Headmaster's Headache (状压DP)
- UVA 10817 Headmaster's Headache 状压DP
- [UVA 10817]Headmaster's Headache[状压DP]
- uva 10817 Headmaster's Headache 状压dp
- UVA 10817 Headmaster's Headache - 状压dp
- UVA 10817 Headmaster's Headache(状压dp)
- uva 10817 Headmaster's Headache
- C实现冒泡排序
- ubuntu开机的的时候只剩下壁纸
- 图解ubuntu中修改计算机名
- 最长公共子序列(LCS)
- 第13周项目 例1.2 计算平均成绩 统计输出优秀人数和不及格人数
- Uva 10817 Headmaster's Headache (DP+ 状态压缩)
- 构建高性能web之路------mysql读写分离实战
- 谈谈jQuery和跨域访问
- Linux下共享内存简单程序示例
- DHNN的状态变换(java)----求稳定状态
- Binder线程处理请求
- Callable
- PHP常用一维数组排序
- 第十三周项目四(2):字符数组排序