校长的烦恼 [状态压缩][DP]
问题描述
某中学开设有s门课程,现有教师m个。今天有n个求职者来应聘新教师。
已知每个人工资和能教授的课程。
在职教师不能辞退,校长想知道,最少支付多少工资就能使得每门课都有至少两名教师能教。
输入格式
第一行,三个整数s,m和n
接下来m行,每行若干个整数,描述一名在职教师的情况:第一个整数,表示该教师的工资,接下来的若干整数表示该教师能教的课程;
接下来n行,每行若干个整数,描述一名求职者的情况:第一个整数,表示该求职者要求的工资,接下来的若干整数表示该求职者能教的课程;
注意,每行末尾有空格
输出格式
一行,一个整数,表示所求结果。
若无解,输出-1
设定一个状态f[i][j],其中i表示至少有一个老师能教这门课,j表示至少有两个老师能教这门课,f[i][j]表示当前状态的最少工资。
最初的状态就是所有在职教师的所在课程和工资。
接下来就从每个课程开始枚举,即从所有课程都至少有两名老师教的状态开始枚举(因为每个来应聘的教师只能够用一次,所以要倒着枚举)。
对于每门课程(不管它现在有几个人教),假设起用第k个应聘者,那么他对当前状态f[i][j]的影响如下:
对于i,显然有A=i|k。对于j,有B=(i&k)|j,因为i和k共同能教的课一定至少有两个老师能教,然后这些课加进j。
所以说,f[A][B]=min{ f[i][j]+Cost[k] }。
答案输出f[1<<s-1][1<<s-1]
这其实和背包很相似,只是用状态压缩的方式实现。
#include<iostream>
#include<cstdio>