1 /* 2 题意:给出一系列的01字符串,问最少要问几个问题(列)能把它们区分出来 3 状态DP+记忆化搜索:dp[s1][s2]表示问题集合为s1。答案对错集合为s2时,还要问几次才能区分出来 4 若和答案(自己拟定)相差小于等于1时,证说明已经能区分了,回溯。否则还要加问题再询问 5 */ 6 /************************************************ 7 * Author :Running_Time 8 * Created Time :2015-8-13 10:54:26 9 * File Name :UVA_1252.cpp 10 ************************************************/ 11 12 #include <cstdio> 13 #include <algorithm> 14 #include <iostream> 15 #include <sstream> 16 #include <cstring> 17 #include <cmath> 18 #include <string> 19 #include <vector> 20 #include <queue> 21 #include <deque> 22 #include <stack> 23 #include <list> 24 #include <map> 25 #include <set> 26 #include <bitset> 27 #include <cstdlib> 28 #include <ctime> 29 using namespace std; 30 31 #define lson l, mid, rt << 1 32 #define rson mid + 1, r, rt << 1 | 1 33 typedef long long ll; 34 const int MAXN = 128 + 10; 35 const int INF = 0x3f3f3f3f; 36 const int MOD = 1e9 + 7; 37 int dp[(1<<11)+10][(1<<11)+10]; 38 int p[MAXN]; 39 char str[13]; 40 int m, n; 41 42 int DFS(int s1, int s2) { 43 if (dp[s1][s2] != INF) return dp[s1][s2]; 44 int cnt = 0; 45 for (int i=1; i<=n; ++i) { 46 if ((p[i] & s1) == s2) cnt++; 47 } 48 if (cnt <= 1) { 49 return dp[s1][s2] = 0; 50 } 51 for (int i=0; i<m; ++i) { 52 if (s1 & (1 << i)) continue; 53 int nex = s1 | (1 << i); 54 dp[s1][s2] = min (dp[s1][s2], max (DFS (nex, s2), DFS (nex, s2 ^ (1 << i))) + 1); 55 } 56 57 return dp[s1][s2]; 58 } 59 60 int main(void) { //UVA 1252 Twenty Questions 61 while (scanf ("%d%d", &m, &n) == 2) { 62 if (!m && !n) break; 63 for (int i=1; i<=n; ++i) { 64 scanf ("%s", str); p[i] = 0; 65 for (int j=0; j<m; ++j) { 66 if (str[j] == ‘1‘) { 67 p[i] |= (1 << j); 68 } 69 } 70 } 71 memset (dp, INF, sizeof (dp)); 72 printf ("%d\n", DFS (0, 0)); 73 } 74 75 return 0; 76 }
时间: 2024-08-02 15:54:45