按照紫书的思路,同时利用位运算来提供所谓的集合信息,要注意前m个教师是必须选的,后n个教师是可选的,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;
int S, M, N;
int cost[150], subject[150];
int result[130][520][520];
int dp(int cur,int s0,int s1,int s2){
if (cur == M + N){
if (s2 == ((1 << S) - 1)) return 0;
return 1 << 30;
}
int& ans = result[cur][s1][s2];
if (ans >= 0) return ans;
ans = 1 << 30;
if(cur>=M) ans = dp(cur + 1, s0, s1, s2);
int m0 = s0&subject[cur], m1 = s1&subject[cur];
s0 ^= m0;
s1 = (s1 ^ m1) | m0;
s2 |= m1;
ans = min(ans, cost[cur] + dp(cur + 1, s0, s1, s2));
return ans;
}
int main(){
while ((cin >> S >> M >> N)&&S&&M&&N){
string t;
getline(cin, t);
memset(subject,0,sizeof(subject));
for (int i = 0; i < M + N; i++){
getline(cin, t);
stringstream is(t);
int a;
is >> a;
cost[i] = a;
while (is >> a){
a--;
subject[i] |= (1 << a);
}
}
memset(result,-1,sizeof(result));
cout << dp(0, (1 << S) - 1, 0, 0) << endl;
}
return 0;
}