http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2146
这道题 我用dfs生成所有子集秒掉了, 但是, 末子大神给出了不用dfs的更快的方法, 枚举就行了, 膜拜= =待我想想
----补充----
今天苦于思索末子大神的算法, 最终找到几个反例, 感觉应该是不对的.
不过我在网上确实找到了不用dfs枚举的算法, 实际上核心就是P个二进制位组成的串, 他的所有子集, 其实就是二进制的0枚举到2^P-1. 待我晚上回家,把这个算法写一下.
1 #include <cstdio> 2 #include <vector> 3 #include <bitset> 4 #include <climits> 5 #include <iostream> 6 using namespace std; 7 8 #define MAX 15 9 10 vector<bitset<MAX> > vec; 11 int P = 0; 12 int N = 0; 13 bitset<MAX> flag; 14 int minre = INT_MAX; 15 void dfs (int cur) { 16 if (cur == P) { 17 //cout<<flag<<endl; 18 bool f = true; 19 for (int i = 0; i < N; ++i) { 20 for (int j = i + 1; j < N; ++j) { 21 bitset<MAX> l = vec[i]; 22 bitset<MAX> r = vec[j]; 23 l = l & flag; 24 r = r & flag; 25 if (l == r) { 26 f = false; 27 } 28 } 29 } 30 if (f) { 31 if (flag.count() < minre) { 32 minre = flag.count(); 33 } 34 } 35 } else { 36 flag[cur] = 0; 37 dfs(cur + 1); 38 flag[cur] = 1; 39 dfs(cur + 1); 40 } 41 } 42 43 int main() 44 { 45 int T = 0; 46 scanf("%d", &T); 47 for (int i = 0; i < T; ++i) { 48 scanf("%d%d", &P, &N); 49 flag.reset(); 50 vec.clear(); 51 minre = INT_MAX; 52 for (int j = 0; j < N; ++j) { 53 bitset<MAX> t; 54 for (int k = 0; k < P; ++k) { 55 int temp = 0; 56 scanf("%d", &temp); 57 t[k] = temp; 58 } 59 vec.push_back(t); 60 } 61 // for (int i = 0; i < N; ++i) { 62 //cout<<vec[i]<<endl; 63 // } 64 dfs(0); 65 printf("%d\n", minre); 66 } 67 return 0; 68 }