这是状压dp的第一道题,题目链接
用d[i][s1][s2]表示处理到第i个人,s1一个人教的科目,s2两个人的教的科目。 1 #include<bits/stdc++.h> 2 using namespace std;
3 //#define IOS ios_base::sync_with_stdio(0); cin.tie(0); 4 #define INF 1000000000 5 int n, m, s, x; 6 int c[130], st[130]; 7 int d[130][1 << 8][1 << 8]; 8 int dp(int i, int s0, int s1, int s2){ 9 if(i == m + n){ return s2 == (1 << s) - 1 ? 0 : INF; } 10 int &ans = d[i][s1][s2]; 11 if(ans >= 0) return ans; 12 // if(d[i][s1][s2]) return d[i][s1][s2]; 13 //int ans = &d[i][s1][s2]; 14 ans = INF; 15 if(i >= m) 16 ans = dp(i + 1, s0, s1, s2);//不选i。
//下面是选i的操作。
17 int m0 = st[i] & s0; 18 s0 ^= m0; 19 int m1 = st[i] & s1; 20 s2 |= m1; 21 s1 = (s1 ^ m1) | m0; 22 ans = min(ans, dp(i + 1, s0, s1, s2) + c[i]); 23 return ans; 24 } 25 int main() 26 { 27 //IOS; 28 string line; 29 while(getline(cin , line)){ 30 memset(st, 0, sizeof(st)); 31 stringstream ss(line); 32 ss >> s >> m >> n; 33 if(s == 0) break; 34 string str; 35 for(int i = 0; i < m + n; i++){ 36 getline(cin, str); 37 stringstream ss(str); 38 ss >> c[i]; 39 while(ss >> x){ 40 st[i] |= (1 << (x - 1)); 41 } 42 } 43 memset(d, -1, sizeof(d)); 44 cout << dp(0, (1 << s) - 1, 0, 0) << endl; 45 46 } 47 48 }