UVa 1252该类的子集的二进制表示方法还需要学习

来源:互联网 发布:打考勤软件 编辑:程序博客网 时间:2024/06/09 08:00
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=150;const int maxs=11;const int INF=0x3f3f3f3f;int d[1<<maxs][1<<maxs];int cnt[1<<maxs][1<<maxs];int p[maxn],n,m;char t[maxs+3];void init(){    memset(cnt,0,sizeof(cnt));    memset(d,-1,sizeof(d));    for(int i=0;i<n;i++)    {        scanf("%s",t);        int la=strlen(t);        for(int j=0;j<la;j++)        {            p[i]=(p[i]<<1)+t[j]-48; //物体转换为二进制整数,p数组一共有n个        }    }    for(int i=0;i<(1<<m);i++)    {        for(int j=0;j<n;j++)            cnt[i][i&p[j]]++;    }}int dp(int s0,int s1){   if(d[s0][s1]!=-1) return d[s0][s1];   if(cnt[s0][s1]<=1) return d[s0][s1]=0;//如果只有一个物体满足条件,则无需再询问   d[s0][s1]=INF;   for(int i=0;i<m;i++)//开始一个一个特征的询问   {       if(s0&(1<<i)) continue;       int& ans=d[s0][s1];       int t0=s0^(1<<i);//^利用^运算,把i加入到s0集合当中       ans=min(ans,max(dp(t0,s1),dp(t0,s1^(1<<i)))+1);   }    return d[s0][s1];}int main(){    while(scanf("%d%d",&m,&n)!=EOF)    {        if(m==0&&n==0)            break;        init();        int ans=dp(0,0);        printf("%d\n",ans);    }   return 0;}

0 0
原创粉丝点击