题目大意:有n件物品,每件物品有m个特征,可以对特征进行询问,询问的结果是得知某个物体是否含有该特征,要把所有的物品区分出来(n个物品的特征都互不相同)最小需要多少次询问?

题目分析:定义dp(s,a)表示询问了的特征集合为s,物体含有特征集合a中的所有特征,但不含特征集合 s^a 中的所有特征时还需的最少询问次数。状态转移方程为dp(s,a)=min(max(dp(s|(1<<k),a|(1<<k)),dp(s|(1<<k),a))+1)。 用记忆化搜索的形式实现即可。

当这样的物体只有一个或一个没有时,便可区分出所有的物品,此时dp(s,a)=0。

代码如下:

# include<iostream>
# include<cstdio>
# include<string>
# include<cstring>
# include<algorithm>
using namespace std; const int INF=0x3f3f3f3f; char p[13];
int dp[1<<11][1<<11],sta[130],m,n; int getVal()
{
int res=0;
for(int i=0;i<m;++i)
if(p[i]=='1')
res|=(1<<i);
return res;
} int DP(int s,int a)
{
if(dp[s][a]!=INF)
return dp[s][a]; int num=0;
for(int i=0;i<n;++i)///在这里,也可以预处理出来以提高效率;
if((sta[i]&s)==a)///"=="的优先级比"&"的高!!!
++num;
if(num<=1)
return dp[s][a]=0; int &ans=dp[s][a];
for(int i=0;i<m;++i){
if(s&(1<<i))
continue;
ans=min(ans,max(DP(s|(1<<i),a),DP(s|(1<<i),a|(1<<i)))+1);
}
return ans;
} int main()
{
while(scanf("%d%d",&m,&n)&&n+m)
{
for(int i=0;i<n;++i){
scanf("%s",p);
sta[i]=getVal();
}
memset(dp,INF,sizeof(dp));
printf("%d\n",DP(0,0));
}
return 0;
}

  

UVA-1252 Twenty Questions (状压DP)的更多相关文章

  1. UVa 1252 Twenty Questions (状压DP+记忆化搜索)

    题意:有n件物品,每件物品有m个特征,可以对特征进行询问,询问的结果是得知某个物体是否含有该特征,要把所有的物品区分出来(n个物品的特征都互不相同), 最小需要多少次询问? 析:我们假设心中想的那个物 ...

  2. UVA - 1252 Twenty Questions (状压dp+vis数组加速)

    有n个物品,每个物品有m个特征.随机选择一个物品让你去猜,你每次可以询问一个特征的答案,问在采取最优策略时,最坏情况下需要猜的次数是多少. 设siz[S]为满足特征性质集合S的特征的物品总数,dp[S ...

  3. 状压DP+记忆化搜索 UVA 1252 Twenty Questions

    题目传送门 /* 题意:给出一系列的01字符串,问最少要问几个问题(列)能把它们区分出来 状态DP+记忆化搜索:dp[s1][s2]表示问题集合为s1.答案对错集合为s2时,还要问几次才能区分出来 若 ...

  4. UVA - 1252 Twenty Questions (状压dp)

    状压dp,用s表示已经询问过的特征,a表示W具有的特征. 当满足条件的物体只有一个的时候就不用再猜测了.对于满足条件的物体个数可以预处理出来 转移的时候应该枚举询问的k,因为实际上要猜的物品是不确定的 ...

  5. UVa 1204 Fun Game (状压DP)

    题意:有一些小孩(至少两个)围成一圈,有 n 轮游戏,每一轮从某个小孩开始往左或者往右伟手帕,拿到手帕写上自己的性别(B,G),然后以后相同方向给下一个. 然后在某个小孩结束,给出 n 轮手帕上的序列 ...

  6. UVa 11825 Hackers' Crackdown (状压DP)

    题意:给定 n 个计算机的一个关系图,你可以停止每台计算机的一项服务,并且和该计算机相邻的计算机也会终止,问你最多能终止多少服务. 析:这个题意思就是说把 n 台计算机尽可能多的分成一些组,使得每组的 ...

  7. UVa 1252 - Twenty Questions(状压DP)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  8. UVa 1252 - Twenty Questions(记忆化搜索,状态压缩dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接:点击打开链接 题目大意 有n个长度为m的二进制串,每个都是不同的. 为了把所有字符串区分开,你可以询问,每次可 ...

  9. UVA 11825 Hackers’ Crackdown 状压DP枚举子集势

    Hackers’ Crackdown Miracle Corporations has a number of system services running in a distributed com ...

  10. UVA 1412 Fund Management (预处理+状压dp)

    状压dp,每个状态可以表示为一个n元组,且上限为8,可以用一个九进制来表示状态.但是这样做用数组开不下,用map离散会T. 而实际上很多九进制数很多都是用不上的.因此类似uva 1601 Mornin ...

随机推荐

  1. SNMP学习笔记之SNMP报文协议详解

    0x00 简介 简单网络管理协议(SNMP)是TCP/IP协议簇的一个应用层协议.在1988年被制定,并被Internet体系结构委员会(IAB)采纳作为一个短期的网络管理解决方案:由于SNMP的简单 ...

  2. 基于Swoole和Redis实现的并发队列处理系统

    背景 由于PHP不支持多线程,但是作为一个完善的系统,有很多操作都是需要异步完成的.为了完成这些异步操作,我们做了一个基于Redis队列任务系统. 大家知道,一个消息队列处理系统主要分为两大部分:消费 ...

  3. 20145302张薇《课程设计》数据恢复——WinHex实践

    20145302张薇<课程设计>数据恢复--WinHex实践 实践内容 使用WinHex破损一个U盘 使用WinHex通过DBR备份数据来修复已损坏U盘 实践详细步骤 1.准备一个文件格式 ...

  4. Oracleシノニムについて

    SYNONYM(シノニム/別名) シノニムとは表やビューなどのオブジェクトにつけた別名のことです. この別名を付けることにより本来の名称とは異なるシノニム名でオブジェクトにアクセスすることができます. ...

  5. P3709 大爷的字符串题

    题意 询问区间众数出现的次数 思路 唯有水题快人心 离散化+莫队 莫队一定要先加后减,有事会出错的 莫队维护区间众数: 维护两个数组,一个数组记录权值为x的出现次数,一个记录出现次数为x的数的个数 a ...

  6. RSA加密解密中pkcs1与pkcs8格式私钥互相转换

    net,ios中rsa加解密使用的是pkcs1,而java使用的是pkcs8 如果是按1024取模(通常都是1024),pkcs1格式的私钥长度应该是812.如果是pkcs8的格式的密钥长度为861. ...

  7. HDU3085(双向BFS+曼哈顿距离)题解

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  8. require的shim解释

    通过require加载的模块一般都需要符合AMD规范即使用define来申明模块,但是部分时候需要加载非AMD规范的js,这时候就需要用到另一个功能:shim,shim解释起来也比较难理解,shim直 ...

  9. Java 类引入 学习记录规整

    之前觉得声明一个类,再把另一个包内的声明数值用第一个类打印出来就可以了(加入引入包类) 结果发现是不对的 看了看demo  得出正确结果    ImportTest 被运行 引入下面的Import类 ...

  10. c#传统SqlTransaction事务和TransactionScope事务

    事务有很多种,看了一些关于事务的问题,这里做下笔记····· 事务时单个的工作单位.如果某一事务成功,则在该事务中进行的所有数据更改均会提交,成为数据库中永久的组成部分.若果事务遇到错误,则必须取消或 ...