题意:给你n个长m的不相同的0,1字符串,每一位都作为该位的特征,每次你都可以提出一个问题,求最少的问题使得所有的字符串都区分开
思路:记忆化搜索,首先建立两个集合,一个作为已问的题目的集合,一个作为那些问题的答案,那么我们可以试着存放该状态下,还有多少没有区分开,直到某状态只有一个或者没有的时候,那么就不需要再提问了,也可以看看学长写的点击打开链接
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int MAXN = 150; const int INF = 0x3f3f3f3f; char state[MAXN][14]; int d[1<<12][1<<12],n,m; int dp(int ques,int ans,vector<int> v){ if (d[ques][ans] != -1) return d[ques][ans]; if (v.size() <= 1) return d[ques][ans] = 0; d[ques][ans] = INF; vector<int> v1,v2; for (int i = 0; i < m; i++){ if (ques & (1<<i)) continue; v1.clear(); v2.clear(); for (int j = 0; j < v.size(); j++){ int x = v[j]; if (state[x][i] == ‘1‘) v1.push_back(x); else v2.push_back(x); } d[ques][ans] = min(d[ques][ans],max(dp(ques|(1<<i),ans|(1<<i),v1),dp(ques|(1<<i),ans,v2))+1); } return d[ques][ans]; } int main(){ while (scanf("%d%d",&m,&n) != EOF && n+m){ for (int i = 0; i < n; i++) scanf("%s",state[i]); vector<int> v; for (int i = 0; i < n; i++) v.push_back(i); memset(d,-1,sizeof(d)); printf("%d\n",dp(0,0,v)); } return 0; }