題意:給你n個兩兩不一樣的零一串,Alice在其中選定一個,Bob去猜,每次詢問某一位是0 or 1。問你最壞狀況下最少要猜幾回。ios
f(22...2)表示當前狀態的最小步數,2表示這位沒肯定,1表示肯定爲1,0表示肯定爲0。spa
首先枚舉去問哪一位,從這些方案中取最小者。blog
這裏的MAX(a,b)進行重定義,若是a,b中存在-1,則爲真的max(a,b),不然爲max(a,b)+1。get
f(222)=min(MAX(f(022),f(122)),MAX(f(202),f(212)),MAX(f(220),f(221)));string
邊界是那些讀入的串爲0,讀入的裏面沒有的串的值爲-1。it
隊友的代碼:io
#include <cmath> #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> using namespace std; int T,top,l,n,f[5000000]; char ch; int dfs(int x,int deep) { if(f[x]!=-2) return f[x]; if(deep==l) return f[x]=-1; int xx=x,temp=1; int nowans=100; for(int i=1;i<=l;++i) { if(xx%3==2) { int xxx=x-temp*2; int ans0=dfs(xxx,deep+1); int ans1=dfs(xxx+temp,deep+1); int tempans=max(ans0,ans1); if(ans0!=-1&&ans1!=-1) tempans++; nowans=min(nowans,tempans); } xx/=3; temp*=3; } return f[x]=nowans; } int main() { scanf("%d",&T); while(T--) { scanf("%d%d",&n,&l); top=1; for(int i=1;i<=l;++i) top=top*3; top-=1; for(int i=0;i<=top;++i) f[i]=-2; for(int i=1;i<=n;++i) { int now=0; for(int i=1;i<=l;++i) { while(ch=getchar(),ch!='0'&&ch!='1'); now=now*3+ch-'0'; } f[now]=0; } printf("%d\n",dfs(top,0)); for(int i=0;i<=top;++i) f[i]=-2; } return 0; }